原文地址:http://www.cnblogs.com/lvdabao/p/jquery-deferred.html?utm_source=tuicool&utm_medium=referral html
看過第一篇,再看jquery領悟不少。jquery
jquery的defferd和ES6中的有很大不一樣,概念相似,名稱不一樣。尤爲是Deferred和ajax的關係,如今也搞不清面試
一、聲明一個Deferredajax
var def = $.Deferred(); //定義一個defferd對象 setTimeout(function(){ console.log('執行完成'); def.resolve('隨便什麼數據'); //此處和ES6的區別 }, 2000); return def; //建議返回 def.promise(); 其實他就是一個返回受限Deferred對象的方法,防止外部亂用
二、Jquery的Deferred的三個狀態:pending resolved rejectedpromise
經過def.state()來返狀態。異步
三、jquery文檔中寫:函數
我不太好理解這個filter,仍是想用fun來表述這個參數的意思,因而至關於:測試
var def = $.Deferred(); def.then(doneFun,failFun,progressFun);
由這三個函數來爲執行的結果進行響應。ES6中只有成功或失敗兩個狀態,jquery來擴充了一下正執行這麼一個狀態。ui
四、比較:done,fail,progress 的區別spa
完成 | 失敗 | 待定 |
|
狀態 | resolved | rejected | pending |
觸發的命令 | def.resolve("XXXX"); | def.reject("XXXX"); | def.notify("XXXX"); |
執行狀態回調 | def.done( doneFun ); | def.fail( failFun ); | def.progress( progressFun) |
then執行回調 |
doneFun | failFun | progressFun |
jquery的同義詞 | $.ajax().success() | $.ajax().error() |
猛地一看,可能不太懂,我把我測試代碼貼上就明白了
def = $.Deferred() def.done(function(data) { console.log("完成" + data); }) //d.resolve("xxxx")來觸發 .fail(function(data) { console.log("未完成" + data); }) //d.reject("xxxx")來觸發 .progress(function(data) { console.log("進行中" + data); }) //d.notify("xxxx")來觸發 //如下代碼功能同上。 def = $.Deferred() def.then(function(data) { console.log("完成" + data); }, function(data) { console.log("未完成" + data); }, function(data) { console.log("進行中" + data); }) //如下爲觸發代碼: def.notify(1) // 進行中1 def.notify(50) // 進行中50 def.resolve("done") // 完成done def.notify(100) // 無任何效果。也就是說只有在pending時,才能notify.
五、def.always( alwaysFun ) 不管成功失敗,都執行該函數。
經測,def.notify() 不會觸發alwaysFun. ajax中的同義詞爲:$.ajax().complete( )
六、$.when的用法
和Es6不一樣的是,接受的不是一個數據。then響應的值數據時,也不是數據。記住這個格式便可
$.when(runAsync(), runAsync2(), runAsync3()) .then(function(data1, data2, data3){ console.log('所有執行完成'); console.log(data1, data2, data3); });
jquery中沒有像ES6中的race方法。
七、ajax與Deferred的關係
該部分照抄原文。沒什麼好補充的,請記住只用done,fail,always便可。
jquery的ajax返回一個受限的Deferred對象,還記得受限的Deferred對象吧,也就是沒有resolve方法和reject方法,不能從外部改變狀態。
$.ajax(/*...*/) .success(function(){/*...*/}) .error(function(){/*...*/}) .complete(function(){/*...*/})
分別表示ajax請求成功、失敗、結束的回調。這三個方法與Deferred又是什麼關係呢?其實就是語法糖,success對應done,error對應fail,complete對應always,就這樣,只是爲了與ajax的參數名字上保持一致而已,更方便你們記憶,看一眼源碼:
deferred.promise( jqXHR ).complete = completeDeferred.add; jqXHR.success = jqXHR.done; jqXHR.error = jqXHR.fail;
complete那一行那麼寫,是爲了減小重複代碼,其實就是把done和fail又調用一次,與always中的代碼同樣。deferred.promise( jqXHR )這句也能看出,ajax返回的是受限的Deferred對象。
jquery加了這麼些個語法糖,雖然上手門檻更低了,可是卻形成了必定程度的混淆。一些人雖然這麼寫了好久,卻一直不知道其中的原理,在面試的時候只能答出一些皮毛,這是很很差的。這也是我寫這篇文章的原因。
jquery中Deferred對象涉及到的方法不少,本文儘可能分門別類的來介紹,但願能幫你們理清思路。總結一下就是:$.Deferred實現了Promise規範,then、done、fail、always是Deferred對象的方法。$.when是一個全局的方法,用來並行運行多個異步任務,與ES6的all是一個功能。ajax返回一個Deferred對象,success、error、complete是ajax提供的語法糖,功能與Deferred對象的done、fail、always一致。就醬。