jQuery 的延迟回调执行序列
Posted
技术标签:
【中文标题】jQuery 的延迟回调执行序列【英文标题】:jQuery's Deferred callback execution sequence 【发布时间】:2013-04-25 02:14:01 【问题描述】:jQuery 的 Deferred/promise 有两种结果:resolved 和 denied。您可以将回调附加到与任一状态关联的 Deferred。附件的条件是完成(与已解决相关)、失败(与拒绝相关)和始终(与两种状态相关)。当状态从挂起变为非挂起时,我一直试图确定回调的顺序,但没有成功;即,对于 done 和 always(或 fail 和 always),对于每个已解决和已拒绝的状态,回调执行的顺序是什么?
【问题讨论】:
我很确定它没有定义。它不应该被真正定义,你永远不需要依赖它。 非常明确。首先,将调用失败或完成。接下来,总是会被调用。它不能是任何其他顺序。回调将触发 fifo 先进先出规则:DEMO. 正如@Beetroot-Beetroot 的演示所表明的那样,它完全是先进先出,而不是 Kevin-B 建议的完成/失败总是先于。应该有人将 Beetroot-Beetroot 的评论作为答案 - 它似乎是正确和明确的。 【参考方案1】:延迟对象按照将回调添加到延迟对象的顺序处理其回调。 done()
没有优先于 always()
的优先级,反之亦然。无论您调用resolved()
还是reject()
,行为都是相同的。
请看下面jsfiddle example。
原题的cmets不正确,或者至少不完全正确。
【讨论】:
【参考方案2】:@Malcolm 的回答确实是正确的。文档在很多地方都提到了它,包括:
deferred.done()
和 deferred.fail()
– “回调按照它们添加的顺序执行。”
deferred.always()
– “当 Deferred 被解决或拒绝时,回调按添加顺序执行”
jQuery.ajax()
– “Promise 回调——.done()
、.fail()
、.always()
和 .then()
——按照注册的顺序被调用。”
实现细节
查看Deferred module,它使用了实现FIFO“回调列表”的Callbacks module。
以下是用于向 Deferred 对象添加回调的调用堆栈:
always()
done()
/ fail()
Callbacks.add()
list.push()
– 回调函数是 pushed 到列表的末尾。
这是解析/拒绝 Deferred 对象的调用堆栈:
resolve()
/ reject()
resolveWith()
/ rejectWith()
Callbacks.fireWith()
Callbacks.fire()
– 列表中的回调使用 a for
loop 按 FIFO 顺序执行。
【讨论】:
以上是关于jQuery 的延迟回调执行序列的主要内容,如果未能解决你的问题,请参考以下文章