deferred对象和promise对象(一)

时间:2022-08-23 11:38:12

个人认为阮一峰老师讲的关于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);

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