Node的機制導不少的任務執行是異步的,通常用回調處理任務的結果。多任務就會致使多層嵌套。javascript
因而Promise就被用來處理這個事情。尤爲是bluebird
的Promise實現功能豐富。java
若是須要一大串的任務所有執行完成以後繼續後面的,那麼就用Promise.all
方法,若是要任務順序執行,並把每次的結果單獨處理就用Promise.reduce
方法。git
這兩個方法組合起來就能夠發揮更加大的威力:github
/** * # Pipeline Utility * * Based on pipeline.js from when.js: * https://github.com/cujojs/when/blob/3.7.4/pipeline.js */ var Promise = require('bluebird'); function pipeline(tasks /* initial arguments */) { var args = Array.prototype.slice.call(arguments, 1), runTask = function (task, args) { // Self-optimizing function to run first task with multiple // args using apply, but subsequent tasks via direct invocation runTask = function (task, arg) { return task(arg); }; return task.apply(null, args); }; // Resolve any promises for the arguments passed in first return Promise.all(args).then(function (args) { // Iterate through the tasks passing args from one into the next return Promise.reduce(tasks, function (arg, task) { return runTask(task, arg); }, args); }); } module.exports = pipeline;
首先使用Promise.all
把參數都轉化成一個個的Promise
而後,用Promise.reduce
挨個執行任務,而且把每個任務的結果依次傳遞到下一個任務。數組
來看看怎麼用的。promise
function modelQuery(options) { return dataProvider.Post.findPage(options); } // Push all of our tasks into a `tasks` array in the correct order tasks = [ utils.validate(docName, {opts: permittedOptions}), utils.handlePublicPermissions(docName, 'browse'), utils.convertOptions(allowedIncludes), modelQuery ]; // Pipeline calls each task passing the result of one to be the arguments for the next return pipeline(tasks, options);
注意: tasks
數組的每個成員都返回一個方法。因此tasks
是一個Function
數組。是一組「任務」。app