当前位置:Web前端 > jquery> 正文

jquery deferred对象

时间:2016-4-15类别:Web前端

jquery deferred对象

jquery deferred对象

一、jquery源码中Deferred的定义

 

  •  
  • JScript 代码   复制
  • 
    jQuery.extend({
        Deferred: function( func ) {
            var tuples = [
                    // action, add listener, listener list, final state
                    [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
                    [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
                    [ "notify", "progress", jQuery.Callbacks("memory") ]
                ],
            ...
     
            // All done!
            return deferred;
        },
        // Deferred helper
        when: function( subordinate /* , ..., subordinateN */ ) {
            var i = 0,
                resolveValues = core_slice.call( arguments ),
                length = resolveValues.length,
                ....
     
            return deferred.promise();
        }
    });
    
    		
  •  

    二、Deferred定义的说明

     

    1、$.Deferred的实现

    (1)、创建三个$.Callbacks对象,分别表示成功,失败,处理中三种状态
    (2)、创建了一个promise对象,具有state、always、then、primise方法
    (3)、通过扩展primise对象生成最终的Deferred对象,返回该对象

     

    2、$.when的实现

    (1)、接受若干个对象,参数仅一个且非Deferred对象将立即执行回调函数
    (2)、Deferred对象和非Deferred对象混杂时,对于非Deferred对象remaining减1
    (3)、Deferred对象总数 = 内部构建的Deferred对象 + 所传参数中包含的Deferred对象
    (4)、所传参数中所有Deferred对象每当resolve时remaining减1,直到为0时(所有都resolve)执行回调

     

     

    三、Deferred对象常用的方法

     

    1、构造函数

    1. var deferred = $.Deferred();  

     

    2、deferred.resolve()

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

    (2)、有段程序,如果我不想马上执行,而是想在这里注册一下,在将来的某个时候让他执行,则可以使用这个方法

  •  
  •  
  • 
         var deferred = $.Deferred();
    
         deferred.done(function () {
    
           $.get(
    
              "content.txt",
    
              function (resp) {
    
                alert(resp);
    
              });
    
         });
    
    
         alert("other things...")
    
    
         setTimeout(function() {
             deferred.resolve()
         }, 3000)
    
    		
  • (3)、代码说明

    先将要执行的代码写上,然后去做其他的事情,等到我想要这段代码执行的时候,只要调用 deferred.resolve();就可以了。

     

    3、deferred.reject()

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

    (2)、reject函数可以接收一个参数,用于传给deferred的failCallback。

  •  
  •  
  • 
        $(function(){
            var dfd = $.Deferred();
            var func1 = function() {alert("1");};
            var func2 = function() {alert("2");};
            
            dfd.fail(func1, [func1, func2], func2);
                    //调用reject方法触发fail事件处理函数
            dfd.reject();
        })
    
    		
  •  

    4、deferred.then()

     

    (1)、用于将done()和fail()合在一起写

    (2)、用于给一个deferred对象添加监听器。

    deferred.then( doneCallbacks, failCallbacks )

     

    参数说明

    doneCallbacks: 一个函数,或者是一组函数,在deferred.resolve时调用


    failCallbacks: 一个函数,或者是一组函数,在deferred.reject时调用

  •  
  • 
    $.get("testURL").then(
        function(){ alert("$.get succeeded"); },
        function(){ alert("$.get failed!"); }
    );
    
    		
  •  

    5、deferred.done()

     

    (1)、操作成功时的回调函数

    (1)、在Deferred对象被resolve时执行

    (2)、可以附加多个回调函数

  •  
  • 
         function doneFunc1() {
    
         alert("doneFunc1");
    
         }
    
     
    
         function doneFunc2() {
    
         alert("doneFunc2");
    
         }
    
    
         deferred.resolve();
    
    				
  •  

    6、deferred.fail()

     

    (1)、操作失败时的回调函数,与.done 相反

    (2)、 在Deferred对象被reject时执行

  •  
  • 
         var deferred = $.Deferred();
    
         deferred.fail(function () {
    
         alert("fail!");
    
         });
    
     
    
         deferred.reject();
    
    		
  •  

    7、deferred.always()

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

  •  
  • 
    var deferred = $.Deferred()
    deferred.always(function() {
        var state = deferred.state()
        if ( state === 'resolved') {
            alert('success')
        } else if (state === 'rejected') {
            alert('fail')
        }
    })
    setTimeout(function() {
        deferred.resolve()
        //deferred.reject()
    }, 3000)
    
    		
  •  

    8、deferred.notify()

    (1)、deferred.resolve和deferred.reject都属于终结性的行为,也就是说,调用了deferred.resolve和deferred.reject后,再也不能对deferred对象进行状态上的改变(resolve, reject, notify, resolveWith, rejectWith, 和 notifyWith)。

    (2)、如果我们想让deferred对象做一些事情,而又不想终结该deferred对象,该怎么办哪?这就是deferred.notify方法的作用。

    (3)、和deferred.progress配对使用

  •  
  • 
         var deferred = $.Deferred();
    
         deferred.progress(function (args) {
    
         alert(args);
    
         });
    
     
    
         deferred.notify("notify1");
    
         deferred.notify("notify2");
    
         deferred.resolve();
    
    		
  •  

     

    四、$.deferred与$.when()一起调用

     

    1、$.when()提供了一种根据Defererred对象的状态来执行回调函数的办法。它接受一个或者多个Defeered对象。

  •  
  • 
        $(function(){
             $.when($.ajax('test.html')).then(function(data, textStatus, jqXHR){
                 console.log(data);
             },function(){
                 alert('failure');
             })
        });
    
    		
  • 2、在只使用一个参数的情况下,$.when()和直接使用Deferred对象没有什么区别,它也返回一个Deferred对象。

    3、$.when()更大的作用在于使用多个Defeered对象时,此时$.when()返回一个包含所有Deferred状态的超级Deferred对象。并且如果有一个Deferred失败,那么这个超级Deferred的状态将为failed,只有在所有Deferred对象都实现时,返回的超级Deferred对象状态才为resolved。

  •  
  • 
        $(function(){
                     //假设test.html不存在,那么将调用fail回调函数,弹出alert对话框
             $.when($.ajax('test.html'), $.ajax('test.html')).then(function(args1,args2){
                 console.log(args1);
             },function(){
                 alert('failure');
             })
        });
    
    		
  • 4、非常适用于 当一个回调函数需要依赖多个ajax请求取回数据才能被触发的情况。

     

     

    五、与ajax等回调函数的关系

     

    1、jQuery书写ajax的风格可以这样写

  •  
  • 
    $.ajax(url)
     .done(success)
     .fail(fail)
    
    		
  •  

    2、Deferred可以添加多个回调

  •  
  • 
    $.ajax(url)
     .done(success1)
     .done(success2)
     .fail(fail2)
     .fail(fail2)
    
    		
  •  

    3、如果多个请求完成后才算成功,则可以用$.when

  •  
  • 
    var ajax1 = $.ajax(url1)
    var ajax2 = $.ajax(url2)
    $.when(ajax1, ajax2).done(success)
    标签:
  • 上一篇下一篇

    猜您喜欢

    热门推荐