<本文譯自http://dojotoolkit.org/reference-guide/dojo/Deferred.html#dojo-deferred>
dojo.Deferred管理着異步線程(Callbacks)之間的通訊。dojo.Deferred封裝了對尚未發生的結果的一系列回調。所有dojo.xhr*函數,也包括很多其它的函數,如dojo.io.script,都使用了dojo.Defferred類。
簡介
dojo.Deferred是一種允許使用者針對那些無法即刻完成的任務,按執行成功或者失敗條件指定回調函數的對象。這些任務通常由dojo.xhrGet調用產生,或者其它進行異步操作的IO函數。
要點是異步任務(甚至是同步任務)可能返回一個dojo.Deferred的實例。使用者可以對這個實例調用'then'函數,以指定當任務完成時需要激發的回調函數。如果在延遲對象(Deferred)執行以後,'then'函數被調用,那麼延遲對象會立即使用任務結果作爲參數來調用這些回調函數。
用法
使用dojo.Deferred並不複雜。當一個函數調用返回一個Deferred對象時,你簡單地調用'then',並將需要在Deferred激發時調用的函數傳給'then'。現在,當你創建一個deferred時,只需簡單地實例化一個Deferred對象並將其返回給調用者。當任務完成時,通過在Deferred對象上調用callback或者'errback'函數來發生任務完成信號,這個操作會使用得該Deferred對象上關聯的回調函數被調用。具體參見下面的例子:
示例1僞代碼:創建和調用一個deferred
<script type="text/javascript">
var deferred = new dojo.Deferred();
setTimeout(function(){deferred.callback({success: true}); }, 1000);
return deferred;
</script>
<譯註:上例演示了作爲Deffered的生產者,如何生成一個Deferred對象,並在適當的時候調用其關聯的callback函數。這裏使用setTimeout函數來模擬了一個異步操作的完成,並以{success:true}作爲該異步操作的結果以及調用callback函數的傳入參數。最後返回了deferred對象,供消費者來關聯回調函數。如果沒有任務回調函數關聯在該deferred對象上,則deferred.callback調用不會產生任何結果。>
示例2僞代碼:給一個deferred對象指定回調函數
<script type="text/javascript">
var deferred = someAsyncFunction();
deferred.then(function(value){
//Do something on success.
},
function(error){
//Do something on failure.
});
</script>
<譯註:上例演示瞭如何向示例1產生的deferred對象添加回調用函數。其中示例1的代碼可以看成是someAsyncFunction()的示例函數定義。注意'then'有兩個參數,一個對應異步任務成功完成時的回調函數,第二個則對應任務異常中止時的錯誤處理函數>
dojo.when()函數是與Deferred對象打交道時另一個有用的工具,它可以將對異步操作和同步操作的結果處理規範化爲同一種處理方式。
Deferred對象還有一個叫做'promise'的只讀屬性,保存着操作的結果。它提供了一個穩定不變的結果對象,以便在各個回調函數之間傳遞,而不擔心被意外改變。
參考
- dojo.when()
- dojo.xhrGet()
- Article on the new design of Deferreds in 1.5: http://www.sitepen.com/blog/2010/05/03/robust-promises-with-dojo-deferred-1-5/