Node.js的promise chain(例子)

・3 分钟阅读

承诺是减少被放逐到回调地狱的机会的绝佳方式。在node.js中,我一直使用Q模块来处理异步代码流。

如果你有一些特定顺序要做的事情,你可以通过使用类似的方式设置一个promise chain:


first_promise()
 .then(function() { return second_promise(); })
 .then(function() { return third_promise(); })
 ...
 .then(function() { return nth_promise(); });

其中*_promise()函数包含一些行为,并且返回承诺最终返回结果的promise对象,一旦返回真实结果,它将启动链中的下一个函数。

好的,这比一堆嵌套的回调更容易读。

如果我们想启动一个异步函数,等到得到结果后再执行下一个承诺的行为会发生什么?

Q通过延迟promise解决了这个问题:


function get_the_async_data() {
 var deferred = Q.defer();

 async_function(arguments, function(result) {
 deferred.resolve(result);
 });

 return deferred.promise;
}

好的,现在我们可以设置一个异步事件链,每个事件都依赖于前面的执行。

如果我们希望立即设置一串异步调用,并等待它们完成(在任何时候,以任何顺序),然后在链中设置下一个保证?

Q提供了一个采用promise数组的简单方法: Q.all()


function get_all_the_things(things) {
 var the_promises = [];

 things.forEach(function(thing) {
 var deferred = Q.defer();
 get_a_thing(thing, function(result) {
 deferred.resolve(result);
 });
 the_promises.push(deferred.promise);
 });

 return Q.all(the_promises);
}

现在我们链中的下一个函数将等待,直到每个被创建的promise承诺得到解决,好东西。

最后,我们可能需要一个基于可变数量操作的promise chain,为此,我们可以执行如下操作:


// create an empty promise to begin the chain
var promise_chain = Q.fcall(function(){});

// loop through a variable length list
// of things to process 
async_operations.forEach(function(async_op) {
 var promise_link = function() {
 var deferred = Q.defer();
 perform_async_op(async_op, function(result) {
 deferred.resolve(result);
 });
 return deferred.promise;
 };

 // add the link onto the chain
 promise_chain = promise_chain.then(promise_link);
});

如果在已成为另一个promise chain的一部分的函数内执行这个操作,则可以:

return promise_chain;

在解决可变长度子链问题之前,主链不会继续。

很整吧!

方玉 profile image