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); }); // 控制台打印各个文件内容 顺序不一定
内容版权声明:除非注明,否则皆为本站原创文章。