深入理解jQuery延遲對象
JavaScript中的延遲對象Promise在ES6中已經(jīng)得到實(shí)現(xiàn),而jQuery中的延遲對象也是類似的。讓我們先來看一個稍顯牽強(qiáng)的例子:當(dāng)點(diǎn)擊添加按鈕時,可以看到span元素被添加并且顏色變?yōu)榧t色
JavaScript中的延遲對象Promise在ES6中已經(jīng)得到實(shí)現(xiàn),而jQuery中的延遲對象也是類似的。讓我們先來看一個稍顯牽強(qiáng)的例子:當(dāng)點(diǎn)擊添加按鈕時,可以看到span元素被添加并且顏色變?yōu)榧t色。在代碼中,我們會發(fā)現(xiàn)一些不同尋常的地方,比如`var dfd new $.Deferred()`,以及在添加事件處理函數(shù)中的 `()`,最后是`(function(){$("span").css("color","red");})`。`$.Deferred()`就是今天我們要介紹的重點(diǎn)——jQuery中的延遲對象。延遲就意味著某段代碼將在將來的某個時間點(diǎn)執(zhí)行。這段代碼展示了一個處理流程,通過調(diào)用新建的延遲對象的`()`方法傳遞了一個匿名函數(shù)表達(dá)式,在點(diǎn)擊事件處理函數(shù)執(zhí)行時調(diào)用了`()`。這種方式利用延遲對象可以改變函數(shù)的執(zhí)行順序。
jQuery延遲對象在實(shí)際應(yīng)用中的價值
盡管在上面的例子中看起來有些多余,將改變顏色的代碼放在一個函數(shù)中然后在點(diǎn)擊時調(diào)用這個函數(shù)更為直接,但延遲對象最常見的應(yīng)用場景還是在AJAX請求中。在上面的代碼中,點(diǎn)擊add后再點(diǎn)擊remove再點(diǎn)擊add,會發(fā)現(xiàn)第二次字體沒有變紅,這是因為延遲對象的狀態(tài)一旦改變就會失效,也就是說它是一次性的。jQuery使用`Deferred`或者`Promise`來實(shí)現(xiàn)延遲對象的功能,基本上它們是相同的,確切地說`Promise`是`Deferred`的一個子類。創(chuàng)建一個延遲對象的方式是`var dfd new $.Deferred()`,延遲對象有三種狀態(tài):pending、resolved、rejected,可以通過`()`方法查看當(dāng)前狀態(tài)。調(diào)用`resolve()`方法后,狀態(tài)會變?yōu)閞esolved,然后執(zhí)行`()`中的函數(shù);調(diào)用`reject()`方法后,狀態(tài)變?yōu)閞ejected,執(zhí)行`()`中的函數(shù)。一旦從pending變?yōu)閞esolved或rejected,`dfd`對象就不會再發(fā)生變化,這也解釋了為什么上面的代碼只在第一次點(diǎn)擊后字體變紅。
利用鏈?zhǔn)秸{(diào)用優(yōu)雅處理代碼邏輯
在`()`中定義了改變字體顏色的函數(shù),在點(diǎn)擊后調(diào)用`resolve()`后,`dfd`的狀態(tài)從pending變?yōu)閞esolved,執(zhí)行`done()`中的方法實(shí)現(xiàn)顏色變紅。`resolve()`和`done()`之間可以傳遞參數(shù),可以修改代碼使得點(diǎn)擊后字體顏色變?yōu)榫G色。此外,`dfd`還有一個叫做`always`的函數(shù),無論狀態(tài)從pending變?yōu)楹畏N狀態(tài),`always`中的函數(shù)都會執(zhí)行。每個`dfd`方法都會返回一個延遲對象,因此`done`、`fail`、`always`都可以進(jìn)行鏈?zhǔn)秸{(diào)用。`dfd`的每個API都可以寫多個,保證函數(shù)的執(zhí)行順序完全按照書寫順序執(zhí)行。
靈活控制代碼執(zhí)行順序的良方
延遲對象可以幫助我們避免嵌套處理過程,讓代碼邏輯更清晰。其中一個重要作用是合并多個AJAX調(diào)用,比如在獲取數(shù)據(jù)A和數(shù)據(jù)B后進(jìn)行一些操作。通過延遲對象輕松實(shí)現(xiàn)這一需求,可以利用jQuery的`$.when()`方法。`$.when()`的參數(shù)可以是Promise對象,也可以是字符串,返回結(jié)果也是一個Promise對象。`notify`和`progress`是`dfd`的另一對組合,可以在`pending`狀態(tài)下調(diào)用`()`,`progress()`中的函數(shù)會執(zhí)行,只要`dfd`處于`pending`狀態(tài),`notify()`可以一直調(diào)用。
通過深入理解jQuery延遲對象,我們可以更好地掌握在實(shí)際項目中如何利用它們來管理異步操作,提高代碼的可讀性和可維護(hù)性,讓程序開發(fā)變得更加高效和優(yōu)雅。