Node.js Q承诺,为什么在使用this()时使用defer()?

时间:2013-01-22 22:55:53

标签: javascript node.js callback deferred promise

我想做类似的事情:

somePromiseFunc(value1)
.then(function(value2, callback) {
    // insert the next then() into this function:
    funcWithCallback(callback);
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();

它不起作用。我无法让它发挥作用。我被建议为此目的使用defer()

他们的own docs说我们应该将延迟用于回调式函数。虽然这很令人困惑,因为他们着名的展平金字塔的例子都是关于回调的,但这个例子太抽象了,无法理解。

因此,我看到很多人使用defer,这就是我所做的:

somePromiseFunc(value1)
.then(function(value2) {
    var promise = q.defer();

    funcWithCallback(function(err, dronesYouAreLookingFor){
        if (!err)
            promise.resolve(dronesYouAreLookingFor);
        else
            promise.reject(new Error(err));
    });
    return promise.promise;
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();

直到我通过检查源代码发现这也有效:

somePromiseFunc(value1)
.then(function(value2) {
    return function() {
        funcWithCallback(arguments[1]);
    };
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();

为什么我不能使用这个更简单的无证版本?

未记载,因为虽然这看起来像展平金字塔那样,但return function(){withCB(arguments[1])}有效,而return function(err, cb){withCB(cb)}却没有。

1 个答案:

答案 0 :(得分:9)

这不是使用promise库的合法方式。正如Q the promises spec中详细说明的那样,从.then回调中返回的任何非承诺都应该直接通过。

当您使用promises时,基本上基于回调的代码应被视为legacy

您有两个基本选项。如果您多次使用funcWithCallback,则可以执行以下操作:

var promisedFunc = Q.nfbind(funcWithCallback);

somePromiseFunc(value1)
.then(function(value2) {
    return promisedFunc();
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();

或者如果你需要传递参数:

var promisedFunc = Q.nfbind(funcWithCallback);

somePromiseFunc(value1)
.then(function(value2) {
    return promisedFunc(value1, value2);
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();

如果你只是一次使用它

somePromiseFunc(value1)
.then(function(value2) {
    return Q.nfcall(funcWithCallback);
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();

或者如果你需要传递参数:

somePromiseFunc(value1)
.then(function(value2) {
    return Q.nfcall(funcWithCallback, value1, value2);
})
.then(function(dronesYouAreLookingFor){
    // Have a party
})
.done();