gre*_*emo 4 asynchronous node.js promise q
如果您使用Node.js编程几天,即使有很好的文档q框架也很难理解.但我喜欢了解它!
var Q = require('q');
var fs = require('fs');
// Make the promise manually (returns a value or throws an error)
var read1 = fs.readFile(fname, enc, function (err, data) {
if(err) throw err;
return data;
});
// Convenient helper for node, equivalent to read1?
var read2 = Q.nfbind(fs.readFile);
// Uh?!
var read3 = function (fname, enc) {
var deferred = Q.defer();
fs.readFile(fname, enc, function (error, text) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.resolve(text);
}
return deferred.promise;
});
};
// Execute
Q.fncall(read1).then(function (data) {}, function (err) {}).done();
Run Code Online (Sandbox Code Playgroud)
是read1,read2与read3相同呢?我可以使用Q.nfbind每一个函数的最后一个参数接受的风格回调的时间function (err, value)?
log*_*yth 11
您的示例中有一些错误.
这不是"手动承诺",这只是进行正常的异步调用.在你的代码中,你readFile立即调用,所以read1它的返回值readFile是undefined.要获得类似的行为read2,read3您需要执行以下操作:
var read1 = function(fname, env, success, error){
fs.readFile(fname, enc, function (err, data) {
// Throwing here would just crash your application.
if(err) error(err);
// Returning from inside 'readFile' does nothing, instead you use a callback.
else success(data);
});
};
Run Code Online (Sandbox Code Playgroud)
// Not equivalent to read1 because of the notes above,
// Equivalent to read3, with the fixes I mention below.
var read2 = Q.nfbind(fs.readFile);
Run Code Online (Sandbox Code Playgroud)
var read3 = function (fname, enc) {
var deferred = Q.defer();
fs.readFile(fname, enc, function (error, text) {
if (error) {
// 'error' is already an error object, you don't need 'new Error()'.
deferred.reject(error);
} else {
deferred.resolve(text);
}
// HERE: Again returning a value from 'readFile' does not make sense.
return deferred.promise;
});
// INSTEAD: Return here, so you can access the promise when you call 'read3'.
return deferred.promise.
};
Run Code Online (Sandbox Code Playgroud)
你确实可以使用nfbind任何以回调作为最后一个参数的东西.使用我的注释,read2并read3实现相同的目标,即创建一个将采用文件名和编码的函数,并返回一个promise对象.
对于那些,你可以这样做:
read2('file.txt', 'utf8').then(function (data) {}, function (err) {}).done();
read3('file.txt', 'utf8').then(function (data) {}, function (err) {}).done();
Run Code Online (Sandbox Code Playgroud)
因为read1,你会这样称呼它:
read1('file.txt', 'utf8', function (data) {}, function (err) {});
Run Code Online (Sandbox Code Playgroud)
标准的承诺已经有所改进,因为这已得到回应,如果你倾向于read3,我建议你做以下事情:
var read4 = function (fname, enc) {
return Q.promise(function(resolve, reject){
fs.readFile(fname, enc, function (error, text) {
if (error) {
// 'error' is already an error object, you don't need 'new Error()'.
reject(error);
} else {
resolve(text);
}
});
});
};
Run Code Online (Sandbox Code Playgroud)
这更符合标准的ES6承诺,并且与bluebird一致,因此您可以更轻松地使代码向前发展.使用上面提到的方法read3还引入了同步抛出异常而不是在promise链中捕获异常的可能性,这通常是不可取的.请参阅延迟反模式.
| 归档时间: |
|
| 查看次数: |
2859 次 |
| 最近记录: |