我的项目涉及使用返回延期承诺的多重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()
处理程序?如何以仅在特定延期承诺被拒绝时调用处理程序的方式构建我的工作流程?
答案 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
失败功能的方式。