jQuery中deferred对象的使用,二

接上一回的内容,漏了一个always()方法,参数也是回调函数,与done和fail不同的是,无论任何情况都执行always方法中的回调。

deferred对象的使用(二)

deferred对象不光可以用在jquery的ajax方法中,他提供了一系列的接口,使它的通用型大大提高。

比如有这样一个耗时比较久的方法

function a(){
  function b(){
    alert('start');
  }  
  setTimeout(b, 3000);  
}

如果要在这个方法之后执行某个回调,就不能用$.when()了,因为当$.when()的参数不为deferred对象是会直接调用done或者always中的回调函数。

这个时候就要使用deferred对象的其他方法了,还是上面的方法,做一些改写

function a(){
  var def = $.Deferred(); // 创建deferred对象  
  function b(){
    alert('start');
    def.resolve(); // 改变deferred对象的状态
  }  
  setTimeout(b, 3000);  
  return def;
}

$.when(a()).done(function(){
  alert("It's callback");
});

分析一下:

1. $.Deferred()方法会创建一个deferred对象

2. def.resolve()会改变deferred对象的状态,deferred对象有三种状态,未完成,成功,失败。

它有resolve()和reject()两个方法,resolve方法可以把对象状态改为成功,reject方法可以把状态改为失败。

又有以上的写法会出现问题,返回的deferred对象可以被外部改变状态,所以还提供了一个promise()方法,这个方法会在deferred对象的基础上返回一个新的deferred对象,不同的是,返回的对象只存在可被观察到状态,而不具备可改变其状态的方法,类似返回了一个只读的deferred对象。

所以同样的例子可以改写成这样

function a(){
  var def = $.Deferred(); // 创建deferred对象  
  function b(){
    alert('start');
    def.resolve(); // 改变deferred对象的状态
  }  
  setTimeout(b, 3000);  
  return def.promise();
}

$.when(a().reject()).done(function(){ // reject()方法无效
  alert("It's callback");
});