jquery 延迟调用的这些模式有什么区别?

what is the difference between these pattern of jquery defered call?

我正在尝试像这样调用一些异步函数。为什么案例A和案例B我失败了,但是案例C成功了?

案例A

firstCall()// try to get esstential parameters(a defered)
.fail(function(){
   //failed :call login function again wait user to input login credential(also a defered)
})
.always(function() {
    //show welcome message
})    

在这种情况下,当fail刚开始执行时,always部分直接执行,无需等待。

案例B

firstCall()// try to get esstential parameters(a defered)
.fail(function(){
    //failed :call login function again wait user to input login 
})
.done(function() {
    //show welcome message
})

在这种情况下,如果执行失败的部分,但永远不会执行完成的部分。

案例 C

firstCall()// try to get esstential parameters(a defered)
.then(null,function(){
     //failed :call login function again wait user to input login 
})
.always(function() {
    //show welcome message
})

在这种情况下,then部分作为失败部分,在then完成后总是可以运行。

我不太清楚为什么会这样 happening.Can 有人进一步解释了吗?谢谢

此答案中的所有外部引用均来自 jQuery Deferred Object documentation 或其中链接的相应方法文档。


案例 A

"...the always part just execute without waiting."

让我们看一下 .fail() 的文档:

...deferred.fail() returns the deferred object, other methods of the deferred object can be chained to this one...

.fail() 方法 returns 原始延迟对象 而不是打开新的承诺。这意味着任何链接到它的事件,虽然它们将按顺序 运行,但不会固有地等待前面的事件完成。您的 .fail() 不会被等待,而是 立即执行

您想要附加的任何回调方法都必须链接到内部函数,从而创建延迟对象的嵌套循环 - 您可以想象如果我们开始深入进行三到四个回调,那会变得多么丑陋。

幸运的是,.then() 正是为了这个目的而存在! 但更多关于案例 C...


CASE B - “在这种情况下,如果执行失败的部分,但永远不会执行完成的部分。”

.done().fail()相反的。根据成功或失败,它们中只有一个会为任何单个延迟对象触发。

deferred.done()

Add handlers to be called when the Deferred object is resolved.

deferred.fail()

Add handlers to be called when the Deferred object is rejected.


案例 C

.then()

Add handlers to be called when the Deferred object is resolved, rejected, or still in progress.

.then().fail() 都处理被拒绝的延迟对象。

但是有一个主要区别:

As of jQuery 1.8, the deferred.then() method returns a new promise...

.then()returns一个新承诺,而.fail()没有。这意味着链接到 .then() 方法的任何方法都将像原始延迟对象一样等待其完成。


总结:

如果您尝试进行顺序等待呼叫,请使用 .then()。这将允许您作为一系列新承诺在链中前进,同时保持原始延迟对象的状态和值。

如果您完成顺序调用并准备好“关闭”延迟对象,请使用 returns 延迟对象的方法,例如 .done().fail(), 或.always().