【jquery】对deferred对象的理解

一、什么是deferred对象?

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象。

简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。

它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。

二、jQuery Deferred用法小结:

(1) $.Deferred() 生成一个deferred对象。

(2) deferred.done() 指定操作成功时的回调函数

(3) deferred.fail() 指定操作失败时的回调函数

(4) deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口。

(5) deferred.resolve() 手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法。

(6)deferred.reject() 这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态变为"已失败",从而立即触发fail()方法。

(7) $.when() 为多个操作指定回调函数。

除了这些方法以外,deferred对象还有二个重要方法,上面的教程中没有涉及到。

(8)deferred.then()

有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。

$.when($.ajax( "/main.php" ))

.then(successFunc, failureFunc );

如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法。如果then()只有一个参数,那么等同于done()。

(9)deferred.always()

这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。

$.ajax( "test.html" )

   .always( function() { alert("已执行!");} );

三、简单代码实现

 1 function Deferred(){
 2     this.state = 0;
 3     this.doneQueue = [];
 4     this.failQueue = [];
 5 }
 6 
 7 Deferred.prototype = {
 8     constructor : Deferred,
 9     promise : function(){
10         return this;
11     },
12     done : function(callback){
13         this.doneQueue.push(callback);
14         if( this.state != 0 ){
15             this._finish();
16         }
17         return this;
18     },
19     resolve : function(){
20         this.state = 1;
21         this.args = arguments;
22         this._finish();        
23     },
24     reject : function(){
25         this.state = 2;
26         this.args = arguments;
27         this._finish();        
28     },    
29     _finish : function(){
30             var queue = [];
31         if (this.state == 1)
32             queue = this.doneQueue;
33         else if (this.state == 2)
34             queue = this.failQueue;
35         for (var i = 0, len = queue.length; i < len; i++) {
36             var cb = queue[i];
37             cb.apply(this, this.args);
38         }
39         return this;
40     }
41 };

demo:

 1 function demo( callback ){
 2     var dtd = new Deferred();
 3     setTimeout(function(){
 4         dtd.resolve();
 5         callback();
 6     }, 1 * 1000);
 7     return dtd;
 8 }
 9 
10 demo(function(){
11     alert(22);
12 }).done(function(){
13     alert(33);
14 });

参考:

原文地址:https://www.cnblogs.com/sniper007/p/3031128.html