2014-12-05 114 views
2

我想要做的事很简单,但我不明白一件小事......的NodeJS/Q:链接承诺依次

var Q = require('q'); 

var funcs = ["first", "second", "third", "fourth"]; 

function main(){ 

// really don't know how to chain sequentially here ... 
    var result = Q(); 

    funcs.forEach(function (f) { 
     result = treat(f).then(f); 
    }); 

} 

function treat(t){ 

    var deferred = Q.defer(); 

    setTimeout(function(){ 
     deferred.resolve("treated "+ t); 
    },2000); 

    return deferred.promise; 
} 

main(); 

我想我的funcs中数组的每一个元素被“处理“顺序,输出会再是这样的:

treated first 
//2 seconds later 
treated second 
//2 seconds later 
treated third 
//2 seconds later 
treated fourth 

我不能做到这一点:(它应该是简单的,我不明白的东西:(

回答

8

从你的例子来看,我会假设,你也是伊迪看到Sequences part of Q readme,但未能理解。

使用

原来的例子“瀑布”模型中,当作为输入到下一个传递的每个函数的输出:

var funcs = [foo, bar, baz, qux]; 

var result = Q(initialVal); 
funcs.forEach(function (f) { 
    result = result.then(f); 
}); 
return result; 

但你只是想执行我们在序列中的所有功能,让你可以简单地每个功能绑定其变量:

var args = ["first", "second", "third", "fourth"]; 

var result = Q(); 
args.forEach(function (t) { 
    result = result.then(treat.bind(null, t)); 
}); 
return result; 

在我的例子treat功能将依次4次调用,result承诺将与最新treat呼叫(所有结果的值来解决以前的呼叫将被忽略)。

诀窍是,.then方法接受一个处理程序,它将在当前的promise被解析并返回一个新的promise后被调用。所以,你应该传递给.then一个应该在你的执行链的下一步调用的函数。 treat.bind(null, t)绑定treat功能与属性t。换句话说,它返回一个新的函数,它会调用treat,传递t作为它的第一个参数。