node使用promise替代回调函数(6)
当然,我们可以再简洁一点
var funcs = [foo, bar, baz, qux]
funcs.reduce(function (pre, current),Q(initialVal){
return pre.then(current)
})
看一个具体的例子
function foo(result) {
console.log(result);
return result + result;
}
// 手动链接
Q('hello').then(foo).then(foo).then(foo);
// 控制台输出: hello
// hellohello
// hellohellohello
// 动态链接
var funcs = [foo, foo, foo];
var result = Q('hello');
funcs.forEach(function (func) {
result = result.then(func);
});
// 精简后的动态链接
funcs.reduce(function (prev, current) {
return prev.then(current);
}, Q('hello'));
对于 promise 链,最重要的是需要理解为什么这个链能够顺序执行。如果能够理解这点,那么以后自己写 promise 链可以说是轻车熟路啊
promise 组合
回到我们一开始读取文件内容的例子。如果现在让我们把它改写成 promise 链,是不是很简单呢?
var Q = require('q'),
fs = require('fs');
function printFileContent(fileName) {
return function () {
var defer = Q.defer();
fs.readFile(fileName, 'utf8', function (err, data) {
if (!err && data) {
console.log(data);
defer.resolve();
}
})
return defer.promise;
}
}
// 手动链接
printFileContent('sample01.txt')()
.then(printFileContent('sample02.txt'))
.then(printFileContent('sample03.txt'))
.then(printFileContent('sample04.txt')); // 控制台顺序打印 sample01 到 sample04 的内容
很有成就感是不是。然而如果仔细分析,我们会发现为什么要他们顺序执行呢,如果他们能够并行执行不是更好吗? 我们只需要在他们都执行完成之后,得到他们的执行结果就可以了
我们可以通过 Q.all([promise1,promise2...]) 将多个 promise 组合成一个 promise 返回。 注意:
1. 当 all 里面所有的 promise 都 fulfil 时,Q.all 返回的 promise 状态变成 fulfil
2. 当任意一个 promise 被 reject 时,Q.all 返回的 promise 状态立即变成 reject
我们来把上面读取文件内容的例子改成并行执行吧
var Q = require('q');
var fs = require('fs');
/**
*读取文件内容
*@private
*/
function printFileContent(fileName) {
// Todo: 这段代码不够简洁。可以使用 Q.denodeify 来简化
var defer = Q.defer();
fs.readFile(fileName, 'utf8', function (err, data) {
if (!err && data) {
console.log(data);
defer.resolve(fileName + ' success ');
} else {
defer.reject(fileName + ' fail ');
}
})
return defer.promise;
}
Q.all([printFileContent('sample01.txt'), printFileContent('sample02.txt'), printFileContent('sample03.txt'), printFileContent('sample04.txt')])
.then(function (success) {
console.log(success);
}); // 控制台打印各个文件内容 顺序不一定
内容版权声明:除非注明,否则皆为本站原创文章。
