Angular 没有从 FS.readFile 获取带有承诺的数据
Angular not getting data from FS.readFile with promises
我正在尝试使用Angular服务来调用使用fs.readFile
或fs.writeFile
,具体取决于按下的按钮类型,以了解节点和角度承诺如何交互。我所拥有的是读取写入文件,但不发回读取数据,也不会抛出任何错误让我了解出了什么问题。
//HTML
<button ng-click="rw('write')">WRITE FILE</button>
<button ng-click="rw('read')">READ FILE</button>
//angular
angular.module('test', [])
.controller('ctrl', function($scope, RWService){
$scope.rw = function(type){
RWService.rw(type)
.then(
function(res){
console.log('success');
},
function(err){
console.log('error');
})
};
})
.service('RWService',['$http', '$q', function($http, $q){
this.rw = function(type){
var promise = $http.get('./rw/' + type);
var dfd = $q.defer();
promise.then(
function(successResponse){
dfd.resolve(successResponse);
},
function(errorResponse){
dfd.reject(errorResponse);
}
);
return dfd.promise;
};
}]);
//node
var fs = require('fs')
, async = require('async')
, Q = require('Q');
var dest = './file.txt';
var rw = {
write: function(data){
data = data.repeat(5);
return Q.nfcall(fs.writeFile, dest, data);
}
, read: function(data){
data = data.repeat(5);
var deferred = Q.defer();
console.log('inside read');
fs.readFile(dest, 'utf8', function(err, data){
if (err){
deferred.reject('some error');
}else{
deferred.resolve(data);
}
});
return deferred.promise;
}
};
module.exports = exports = rw;
//node server
app.get('/rw/:type', function(req, res, next){
var type = req.params.type;
var data = 'some text string'n';
if (type == 'write'){
//omitted fro brevity
}else{
rw.read(data)
.then(function(response){
return {'response': response};
})
.catch(function(err){
return {'index.js error': err};
});
}
});
我构建了这篇博文的角度$q
部分。
下面是代码的原生 Promise 实现。
var fs = require('fs');
var dest = './file.txt';
var rw = {
write: function(data){
return new Promise(function (resolve, reject) {
data = data.repeat(5);
fs.writeFile(function (err, result) {
if (err) return reject(err.message);
return resolve(result);
});
});
},
read: function(data){
return new Promise(function (resolve, reject) {
data = data.repeat(5);
fs.readFile(dest, 'utf8', function(err, contents) {
if (err) return reject(err.message);
return resolve(contents.toString());
});
});
}
};
module.exports = exports = rw;
[编辑:我刚刚更改了代码以将data=data.repeat(5)
放入承诺工厂方法中。基本上,如果有什么东西可以引发异常,你应该尝试把它放在那个 promise 函数中,否则你再次冒着再次默默杀死脚本的风险。
几点评论:
返回deferred
非常有用,但您必须小心使用它的方式。我个人仅在异步代码无法包装在简单函数中时才使用它(例如在其构造函数中创建承诺并在不同的子方法中解析/拒绝的类实例(。在您的情况下,可能正在发生的事情是脚本以一种fs.readFile()
永远不会被调用的方式失败 - 因此永远不会达到deferred.resolve()
和deferred.reject()
。在这种情况下,您需要使用 try/catch 并始终在其中调用deferred.reject()
。这是很容易避免的大量额外工作。
相反,您应该尝试使用上面看到的 Promise 的原版标准实现。
最后,Q
是一个开创性的图书馆,基本上首先教会了世界如何做承诺,但它已经多年没有更新了,而且从来没有特别丰富或快速。如果您需要更多功能,请查看 when.js*、kew 或 Bluebird(请注意,Bluebird 声称是最快的,但我个人发现这是不真实的。
(*我真的很喜欢和when一起工作.js发现使用愚蠢的原生承诺有点痛苦,但嘿,标准就是标准。
[编辑:在事物的角度方面添加细节]
因此,根据您的评论,我怀疑您也在寻找以下内容。你会看到,我在这里用$http.get()
作为唯一的应许。一旦你进入一个承诺,就不需要使用defer()
,所以实际上甚至不需要包含$q
。
对不起,我从来没有用过service()
.甚至 Angular 自己关于创建服务的文档也使用 factory()
方法,这就是我在这里使用的。
.factory('RWService',['$http', function($http){
return {
rw: function (type) {
// $http returns a promise. No need to create a new one.
return $http.get('./rw/' + type)
.then(function (response) {
// You can do other stuff here. Here, I am returning the
// contents of the response. You could do other stuff as
// well. But you could also just omit this `then()` and
// it would be the same as returning just the response.
return response.data;
})
.catch(function (err) {
// You can do other stuff here to handle the error.
// Here I am rethrowing the error, which is exactly the
// same as not having a catch() statement at all.
throw err;
});
}
};
}]);
如果你阅读了上面代码中的注释,你应该意识到你可以像这样编写相同的代码:
.factory('RWService',['$http', function($http){
return {
rw: function (type) {
return $http.get('./rw/' + type);
}
};
});
这里唯一的区别是 RWService.rw(( 最终将解析整个响应对象而不是响应数据。
这里要记住的是,你可以(而且绝对应该(尽可能多地回收你的承诺。基本上,您需要了解的有关承诺的只是:
- 每个承诺都有一个
then
和catch
的方法,你可以把你的逻辑包裹起来; - 每一个
then
和catch
都作为新的承诺回归; - 如果你在任何
then
或catch
中抛出异常,你会被直接抛到下一个catch
,如果有的话; - 如果你从任何
then
或catch
返回一个值,它将作为参数传递给链中的下一个then
; - 当链用完
then
,或者你抛出异常并且没有更多的catch
ES,承诺链结束; -
then
和catch
都很快,但它们仍然是异步的,所以如果你真的不需要它们,就不要向承诺链添加新元素。
- “未捕获(在承诺中)”在获取“then”方法中调用拒绝函数时
- 如何获取 Ember 组件对象内部承诺成功或错误回调
- es6 获取/承诺上下文
- 角度承诺:如果可用,从缓冲区获取数据
- 如何使用 Parse.promise javascript 定义一个承诺数组并获取结果数组 [parse.com]
- 如何在解决承诺后从承诺对象获取值
- 是否可以覆盖本机获取 API 以使用所需的承诺库而不是本机浏览器承诺
- 从异步函数返回的承诺中获取值
- Angular 没有从 FS.readFile 获取带有承诺的数据
- 从承诺响应中获取价值
- 从承诺中获取数据,而不是返回承诺
- AngularJS承诺在foreach中获取数据
- 承诺获取和处理数组
- 无法获取属性'那么'使用承诺
- 使用SeleniumWD作为承诺从标签文本中获取输入
- 从q.js承诺链中的任何承诺中获取和设置一个值
- 无法使用承诺获取对象
- 如何在承诺中获取数据数组
- $location.path()从承诺中获取
- 如何使用承诺获取失败ajax请求的URI