首页 > 代码库 > deferred对象和promise对象(一)

deferred对象和promise对象(一)

个人认为阮一峰老师讲的关于deferred对象是最容易理解的。

deferred对象是jquery的回调函数解决方案。解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。

deferred对象的功能:

1.将ajax操作改为链式

对于$.ajax()操作完成之后,如果使用的是低于1.5版本的jquery,返回的是XHR对象,高于1.5版本返回的是deferred对象。deferred对象可进行链式操作。

     $.ajax({
            url:"test.html",
            success:function(){},//success方法指定操作成功后的回调函数
            error:function(){}//error方法指定操作失败后的回调函数
        })
        //新的写法
        $.ajax("test.html")
        .done(function(){})//done()相当于success方法
        .failed(function(){})//failed()相当于error方法

2.指定同一操作的多个回调函数

deferred对象允许自由添加多个回调函数,回调函数按添加顺序执行

         $.ajax("test.html")
        .done(function(){})
        .failed(function(){})
        .dene(function(){})//直接将多个方法加在后面

3.为多个操作指定回调函数

deferred对象允许为多个事件指定一个回调函数,利用$.when()方法

//先执行两个操作$.ajax("test1.html")和$.ajax("test2.html"),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数
    $.when($.ajax("test1.html"), $.ajax("test2.html"))
   .done(function(){})
   .fail(function(){});

4.普通操作的回调函数接口

deferred对象将回调函数的接口从ajax操作扩展到了所有操作。$.when()的参数只能是deferred对象

var wait = function(){
   alertvar tasks = function(){
       alert("执行完毕!");
   };
      setTimeout(tasks,5000);
};

为wai函数添加回调函数

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

存在问题:dtd是全局变量,容易被修改,解决办法:jquery的deferred.promise()方法。在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),从而使得执行状态不能被改变。

第一种方法:

var dtd = $.Deferred(); // 新建一个Deferred对象
var wait = function(dtd){
    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(); // 此时,这个语句是无效的

第二种方法

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

  setTimeout(tasks,5000);
  return dtd.promise(); // 返回promise对象
  };
  $.when(wait())
  .done(function(){ alert("哈哈,成功了!"); })
  .fail(function(){ alert("出错啦!"); });
第三种方法:使用deferred对象的构造函数$.Deferred()
$.Deferred(wait)
.done(function(){ alert("哈哈,成功了!"); })
.fail(function(){ alert("出错啦!"); });
//jQuery规定,$.Deferred()可以接受一个函数名(注意,是函数名)作为参数,$.Deferred()所生成的deferred对象将作为这个函数的默认参数。

第四种方法:在wait方法上直接部署deferred对象

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

困了,今天先到这里,明天早上继续~





deferred对象和promise对象(一)