<本文译自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/