Node.js Q承诺,为什么要使用defer()而不是this()?

7

我想做类似于:

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

这并没有起作用,我没能使它工作。有人建议我使用 defer() 来实现这个目的。

他们自己的文档中说我们应该在回调函数中使用 deferreds。虽然这很令人困惑,因为他们著名的“降低金字塔高度”例子都是关于回调的,但这个例子过于抽象难以理解。

因此,我看到许多人都在使用 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)}则不能。


我认为他们只是向您展示如何使用“defer”将回调样式函数转换为使用promises,并且更明确的示例使所有参数更清晰。Promise可以返回,存储在数据结构中,并与其他Promise任意组合。这是Promise的全部(部分)目的。如果您有一个特殊情况,没有它们会更短,请务必使用它。但是,如果以后需要重构,则可能需要将其转换为Promise;就是这样。 - Jonathan Tran
但是,如果将一个函数包装在返回的函数中是一种合法的方式来将then()插入回调函数中,那么他们为什么不记录这个呢? 更具体地说,未记录的return function(){withCB(arguments[1])}可以工作,但return function(err, cb){withCB(cb)}则不行。 - Redsandro
1个回答

10
这不是使用 Promise 库的合法方式。正如 Q 旨在遵守的 Promise 规范 所详细说明的那样,您从未返回的任何东西.then 回调不是 Promise 应直接通过。

基本上,当您使用 Promise 时,回调为基础的代码应被视为 遗留代码

您有两个基本选项。如果您多次使用 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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接