JQuery 中利用 Deferred 物件提供類似 ES2016(aka. es7) 中 Promise 的功能。
JQuery 中的 AJAX 請求函數傳回的就是 Deferred 物件。
透過使用 Defered 讓非同步呼叫更加可讀,實現進階的用法(指定多個回呼函數/等待多個 AJAX 請求)。
JQuery中傳統的AJAX請求
1 |
|
使用Deferred 的AJAX請求
1 |
|
這篇文章會著重分析Deferred/Promise 的狀態變化過程,並講述Deferred 物件在實際編碼中的應用。
使用者可以使用Deferred
函數來建立Deferred 物件
1 |
|
Deferred 物件有以下三種狀態
pending
#rejected
resolved
Deferred 物件可以從pending狀態轉換到rejected狀態或是resolved.
這種狀態的轉換是單向的,也就是說一旦Deferred物件的狀態是rejected/resolved, 對象的狀態將不可變。
JQuery 提供了三個函數來檢視/修改Deferred物件的狀態:
##deferred.state (), 傳回字串表示目前Deferred 物件的狀態
deferred.reject(), 將物件的狀態設為rejected
deferred.resolve(), 將物件的狀態設定為resolved
1 |
|
then 方法接受兩個函數作為參數,當物件的狀態變成resolved, 第一個函數會被呼叫。當物件的狀態變成 rejected, 第二個函數會被呼叫。
第一個函數接受一個參數,該參數是defered.resolve
函數被呼叫時傳遞的第一個參數。
第二個函數接受一個參數,該參數是
defered.reject函數被呼叫時傳遞的第一個參數。
1 |
|
1 |
|
使用done 方法可以指定當deferred 物件狀態變成resolved 時呼叫的函數
1 |
|
使用fail 方法可以指定當deferred 物件狀態變成rejected 時呼叫的函數#
1 |
|
always 方法接受一個函數作為參數,只要Deferred 物件的狀態發生變化,函數就會被呼叫。鍊式呼叫因為then/done/fail 函數返回的仍然是類別Deferred 對象,所以我們可以使用他們來指定多個回調函數.
下面這個範例用done/fail 來指定多個
1 |
|
promise 方法來取得該物件的Promise 物件。 =
Promise 物件有以下特點:
reject/
resolve 方法
state() 方法取得跟它綁定的Deferred 的狀態
then/
done/
fail 方法來指定回呼函數
1 |
|
then 方法傳回的是一個新的Promise 物件
1 |
|
使用 then 方法我们需要明白的几个关键点是:
Deferred 对象的
then
方法, 会创建一个新的 Deferred 对象,并返回新 Deferred 对象的 Promise 对象。
而且then
方法返回的对象 跟 Deferred 对象的 Promise 对象不相等, 多次调用 then 对象会产生多个 Deferred 对象。
下面的例子对比了多次调用 then 方法产生的 Promise 对象
1 |
|
Deferred 对象状态发生变化后, 等待一段时间后 then 方法产生的 Promise 对象的状态才会发生相应的变化
1 |
|
Deferred 对象的状态发生改变后,then 方法产生的 Promise 对象的状态并没有立即发生变化, 而是等待了一段时间后才改变。
这段时间内,发生了什么那?
我们以调用 Deferred 对象的 resolve 方法作为例子来说明。 调用 reject 方法的情况与此类似。
首先假设我们构造了Deferred 对象 d1
然后调用 then 方法,并且传入两个函数作为参数 fun1, fun2: var p2 = d1.then(fun1, fun2)
调用 d1.resolve(data)
方法将 d1 的状态设置为 resolved, 此时d1 的状态是 resolved, p2 的状态是 pending
fun1 会被调用, 参数为 d1.resolve
方法的参数: var new_data = fun1(data)
假设 p2 对应的 Deferred 对象是 d2.
d2 的 resolve 方法会被调用, 参数为 fun1 的返回值: d2.resolve(new_data)
p2 的状态变为 resolved
p2 的回调函数会被调用
下面的代码展示了 then 方法产生的 Promise 对象的状态变化。以及如何给回调函数传递参数
1 |
|
明白了 Deferred 的原理,我们就可以使用 Deferred.
下面一段代码定义了一个函数, 在函数中定义了一些耗时的操作。
函数返回 Promise 对象, 可以使用 done/fail/then 注册回调函数
1 |
|
跟 ES2016 中 Prmomise.all
函数类似。
JQuery 提供了 when
函数, 它可以接受多个 Deferred/Promise 对象作为参数。并返回一个 Promise 对象。
新的 Promise 对象会等待参数中所有的对象状态变为 resolved/reject。
如果参数中任何一个对象的状态变为 rejected, 那么 Promise 对象的状态变为 rejected。 否则变为 resolved。
1 |
|
以上是JQuery Deferred 物件剖析的詳細內容。更多資訊請關注PHP中文網其他相關文章!