当几个'then'处理程序被链接到延迟时,为什么要调用多个'fail'处理程序?

时间:2013-04-19 16:23:20

标签: javascript jquery jquery-deferred promise

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

我理解.done().then()之间的区别在于.then()会返回新的承诺。在我的例子中,我希望如果第一个延迟被拒绝,那么只会执行第一个.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()处理程序?如何以仅在特定延期承诺被拒绝时调用处理程序的方式构建我的工作流程?

2 个答案:

答案 0 :(得分:4)

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

then()接受以下论点:

then( doneFilter , failFilter )

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

引自the docs

  

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

由于没有给出failFilter参数,then()只是转发第一个promise的状态,触发第二个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 

答案 1 :(得分:1)

这是因为then返回一个新的promise(结果通过管道传递给它的回调返回的promise的结果)。

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

如果只想让它在实际运行时运行,只需更改管理then失败功能的方式。