Node.js Q 承诺,既然可以使用 this(),为啥还要使用 defer()?

Posted

技术标签:

【中文标题】Node.js Q 承诺,既然可以使用 this(),为啥还要使用 defer()?【英文标题】:Node.js Q promises, why use defer() when you can use this()?Node.js Q 承诺,既然可以使用 this(),为什么还要使用 defer()? 【发布时间】:2013-01-06 08:02:17 【问题描述】:

我想做这样的事情:

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 说我们应该为回调风格的函数使用延迟。虽然这很令人困惑,因为他们著名的 flatten the pyramid 示例都是关于回调的,但是这个示例太抽象了,无法遵循。

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

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();

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

未记录,因为虽然这看起来像 flatten the pyramid 所做的那样,return function()withCB(arguments[1]) 有效,而 return function(err, cb)withCB(cb) 无效。

【问题讨论】:

我认为他们只是在向您展示如何将回调样式函数转换为使用带有defer 的承诺,更明确的示例可以更清楚地说明所有参数是什么。一个promise可以被返回,存储在一个数据结构中,并且可以与其他promise任意组合。这是(部分)承诺的全部意义。如果您有一个没有它们的特殊情况,那么一定要使用它。但是如果你稍后重构,你可能需要将它转换为一个 Promise;就是这样。 但是如果在返回的函数中包装一个函数是在回调中插入then() 的合法方式,他们不会记录这一点吗?更具体地说,无证 return function()withCB(arguments[1]) 有效,但 return function(err, cb)withCB(cb) 无效。 【参考方案1】:

这不是使用 Promise 库的合法方式。正如 Q 旨在遵守的 the promises spec 中详述的那样,您从 .then 回调返回的任何不是承诺的东西都应该直接传递。

当您使用 Promise 时,基本上基于回调的代码应被视为 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();

【讨论】:

以上是关于Node.js Q 承诺,既然可以使用 this(),为啥还要使用 defer()?的主要内容,如果未能解决你的问题,请参考以下文章

node.js 中的嵌套承诺是不是正常?

如何在 node.js 中实际使用 Q Promise?

Node js,使用带有Q promise的mongoose不会调用reject函数

使用 Q 承诺 - 有没有办法减少这段代码的重复性?

Node.js 从函数返回一个承诺

为啥在使用promise时使用Q,bluebird框架? [复制]