1

我的项目涉及使用返回延迟承诺的多个 API 的工作流。我正在使用 jQuery 1.8

.done()我知道和之间的区别在于.then()返回.then()一个新的承诺。在我的示例中,我希望如果第一个 deferred 被拒绝,则只有第一个.fail()处理程序将被执行,因为第二个处理程序链接到新的 Promise。在执行中,两个失败处理程序都被执行。

var firstDeferred = $.Deferred(), secondDeferred = $.Deferred();

firstDeferred.promise()
.fail(function (error) {
    console.log(error);
})
.then(function () {
    return secondDeferred.promise();
})
.fail(function (error) {
    console.log(error);
});

firstDeferred.reject('first deferred object');
//secondDeferred.reject('second deferred object');

我的预期结果:

> first deferred object

实际结果:

> first deferred object
> first deferred object

为什么两个.fail()处理程序都被调用?如何构建我的工作流程,使处理程序仅在特定的延迟承诺被拒绝时才被调用?

4

2 回答 2

4

您没有将任何内容链接到您在then()回调中返回的承诺,因为该回调永远不会被执行。

then()接受这些论点:

then( doneFilter , failFilter )

您的回调是第一个参数,因此它是doneFilter. 但是第一个承诺失败了,所以then()不调用你的回调。它调用failFilter,但你没有为第二个参数传递任何东西。

引用文档

如果使用的过滤器函数为 null 或未指定,则 promise 将被解析或拒绝,并使用与原始值相同的值。

由于failFilter没有给出参数,所以then()只转发第一个承诺的状态,这会触发第二个fail()处理程序。

这有效:

var firstDeferred  = $.Deferred(),
    secondDeferred = $.Deferred();

firstDeferred.promise()
.fail(function (error) {
    console.log(error);
})
.then(null, function () { // Notice the null
    return secondDeferred.promise();
})
.fail(function (error) {
    console.log(error);
});

firstDeferred.reject('first deferred object');
secondDeferred.reject('second deferred object');

其中记录:

first deferred object
second deferred object 
于 2013-04-19T19:07:34.693 回答
1

发生这种情况是因为then返回了一个新的 Promise(该结果通过管道传递到其回调返回的 Promise 的结果)。

一个 Promise 可以有两种最终状态:已解决或失败。因此,由于第一个 deferred 失败了,第二个永远无法解决,所以它失败了。如果then没有冒泡失败,你会发现自己有一个无限期的未决承诺。这可能是内存泄漏的风险。

then如果您只希望它在实际运行时运行,则只需更改管理失败功能的方式即可。

于 2013-04-19T19:07:22.397 回答