link jQuery Deferred
Deferred 是作为 Ajax 模块大规模重写的一部分添加的,由 Julian Aubourg 领导,遵循 CommonJS Promises/A 设计。虽然 1.5 及以上版本包含 deferred 功能,但以前版本的 jQuery 接受了在请求完成或出错时调用的回调的 jQuery.ajax()
,但遭受了严重的耦合——同样的原则会驱使使用其他语言或工具包的开发人员选择延迟执行。
实际上,jQuery 的版本为您提供了回调管理方式的若干增强功能,为您提供了更灵活的方法来提供回调,无论原始回调分派是否已触发。还值得注意的是,jQuery 的 Deferred 对象支持将多个回调绑定到特定任务的结果(而不仅仅是一个),而任务本身可以是同步的或异步的。
jQuery 实现的核心是 jQuery.Deferred
——一个可链式构造函数,它能够创建新的 deferred 对象,该对象可以检查 promise 的存在以确定是否可以观察该对象。它还可以调用回调队列并传递同步和异步函数的成功。需要注意的是,任何 Deferred 对象的默认状态都是未解决的。可以通过 .then()
或 .fail()
添加到其中的回调会排队,并在进程的稍后阶段执行。
您可以将 Deferred 对象与 jQuery 中作为 $.when()
实现的 when() 承诺概念结合使用,以等待所有 Deferred 对象的请求完成执行(即所有承诺都已兑现)。从技术角度讲,$.when()
实际上是一种基于表示异步事件的任意数量的承诺执行回调的方式。
下面结合 .then()
可以看到 $.when()
接受多个参数的示例
1
2
3
4
5
6
7
8
9
10
11
12
13
|
|
jQuery 中提供的 $.when()
实现非常有趣,因为它不仅解释了延迟对象,而且在传递不是延迟的参数时,它会将这些参数视为已解决的延迟,并立即执行任何回调(doneCallbacks
)。还值得注意的是,除了公开 deferred.then()
之外,jQuery 的延迟实现还支持 deferred.done()
和 deferred.fail()
方法,这些方法也可用于向延迟队列添加回调。
现在,我们将看一个使用许多延迟功能的代码示例。这个非常基本的脚本首先使用 $.get()
(它将返回一个类似承诺的对象)来使用(1)外部新闻提要和(2)反应提要来提取最新评论。收到这两个请求后,将调用 showAjaxedContent()
函数。showAjaxedContent()
函数返回一个承诺,当两个容器的动画完成时,该承诺将得到解决。当 showAjaxedContent()
承诺得到解决时,将调用 removeActiveClass()
。removeActiveClass()
返回一个承诺,该承诺在经过 4 秒后在 setTimeout()
内得到解决。最后,在 removeActiveClass()
承诺得到解决后,将调用最后一个 then()
回调,前提是在此过程中未发生任何错误。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
|