jQuery的deferred对象学习笔记

普通异步调用:
 $.ajax({
    url: "test.html",
    success: function(){
      alert("哈哈,成功了!");
    },
    error:function(){
      alert("出错啦!");
    }
  });


延迟对象的使用:
  $.ajax("test.html")
  .done(function(){ alert("哈哈,成功了!"); })
  .fail(function(){ alert("出错啦!"); });


添加多个回调:

  $.ajax("test.html")
  .done(function(){ alert("哈哈,成功了!");} )
  .fail(function(){ alert("出错啦!"); } )
  .done(function(){ alert("第二个回调函数!");} );


集成多个回调:

  $.when($.ajax("test1.html"), $.ajax("test2.html"))
  .done(function(){ alert("哈哈,成功了!"); })
  .fail(function(){ alert("出错啦!"); });

普通带回调的函数用延迟对象改造:


  var wait = function(){
       var dtd = $.Deferred(); // 新建一个deferred对象
    var tasks = function(){
      alert("执行完毕!");
      dtd.resolve(); // 改变deferred对象的执行状态
    };
    setTimeout(tasks,5000);
    return dtd;
  };

延迟对象本质就是个状态机,jQuery规定,deferred对象有三种执行状态----未完成,已完成和已失败。如果执行状态是"已完成"(resolved),deferred对象立刻调用done()方法指定的回调函数;如果执行状态是"已失败",调用fail()方法指定的回调函数;如果执行状态是"未完成",则继续等待,或者调用progress()方法指定的回调函数(jQuery1.7版本添加)。
刚开始创建的Promise对象处于pending状态,只能从pending变成resolved或者是从pending变成rejected状态。

dtd.resolve()的意思是,将dtd对象的执行状态从"未完成"改为"已完成",从而触发done()方法。
deferred.reject()方法,作用是将dtd对象的执行状态从"未完成"改为"已失败",从而触发fail()方法。
状态的改变是固定的从"未完成"改为"已完成"或者从"未完成"改为"已失败"不能逆向改变。
progress()和notify()能够用来实现进度条效果,因为notify()允许调用多次,而reject()和resolve()只能调用一次。这个很好理解,因为一旦状态变成resolved或者是rejected,就不能再改变其状态,也没有必要。

延迟对象暴露后可能被外部改变状态:


  var wait = function(dtd){
       var dtd = $.Deferred(); // 新建一个Deferred对象
    var tasks = function(){
      alert("执行完毕!");
      dtd.resolve(); // 改变Deferred对象的执行状态
    };
    setTimeout(tasks,5000);
    return dtd;
  };
  $.when(wait(dtd))
  .done(function(){ alert("哈哈,成功了!"); })
  .fail(function(){ alert("出错啦!"); });
  dtd.resolve();


为了避免这种情况,jQuery提供了deferred.promise()方法。它的作用是,在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),从而使得执行状态不能被改变。


  var wait = function(dtd){
        var dtd = $.Deferred(); // 新建一个Deferred对象
    var tasks = function(){
      alert("执行完毕!");
      dtd.resolve(); // 改变Deferred对象的执行状态
    };

    setTimeout(tasks,5000);
    return dtd.promise(); // 返回promise对象
  };
  var d = wait(dtd); // 新建一个d对象,改为对这个对象进行操作
  $.when(d)
  .done(function(){ alert("哈哈,成功了!"); })
  .fail(function(){ alert("出错啦!"); });
  d.resolve(); // 此时,这个语句是无效的


有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。
  $.when($.ajax( "/main.php" ))
  .then(successFunc, failureFunc );


deferred.always()
这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。
  $.ajax( "test.html" )
  .always( function() { alert("已执行!");} );


进度提示示例:

  html元素:

    <div id="test1"></div>
    <div id="test2"></div>
    <button οnclick="runDtdDemo('test1');">test1</button>
    <button οnclick="runDtdDemo('test2');">test2</button>

  js脚本:
        function dtdDemo(){
            var dtd = $.Deferred();
            var counter = 0,
                doStep = function(){
                    counter++;
                    dtd.notify(counter  + dtd.state());
                    if(counter >= 100){
                        clearInterval(intervalId);
                        counter = 0;
                        dtd.resolve({state:dtd.state()});
                    }
                };
            var intervalId = setInterval(doStep,100);
            return dtd.promise();
        }

        function runDtdDemo(el){
            var mydtd = dtdDemo()
                .progress(function(progress){
                    $("#"+el).html(progress);
                })
                .done(function(result){
                    $("#"+el).html("ok!" + mydtd.state());
                });
        }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值