首页 > 代码库 > jQuery的deferred对象

jQuery的deferred对象

今天学习jQuery API的时候看到deferred部分,以前也没有接触使用过,看的毫无头绪,于是找资料学习了一番。
deferred对象代表了将要完成的某种操作,并提供了一些方法,帮助用户使用。它是jQuery对Promises接口的实现。由于JavaScript单线程的特点,如果某个操作耗时很长,其他操作就必需排队等待。为了避免整个程序失去响应,通常的解决方法是将那些排在后面的操作,写成“回调函数”(callback)的形式。这样做虽然可以解决问题,但是有一些显著缺点:
回调函数往往写成函数参数的形式,导致函数的输入和输出非常混乱,整个程序的可阅读性差;
回调函数往往只能指定一个,如果有多个操作,就需要改写回调函数。
整个程序的运行流程被打乱,除错和调试的难度都相应增加。
 
Promises就是为了解决这些问题而提出的,它的主要目的就是取代回调函数,成为非同步操作的解决方案。它的核心思想就是让非同步操作返回一个对象,其他操作都针对这个对象来完成。比如,假定ajax操作返回一个Promise对象。
1 var promise = get(‘http://www.example.com‘);
然后,Promise对象有一个then方法,可以用来指定回调函数。一旦非同步操作完成,就调用指定的回调函数。
1 promise.then(function (content) {2     console.log(content)3 });
可以将上面两段代码合并起来,这样程序的流程看得更清楚。
1 get(‘http://www.example.com‘).then(function (content) {2     console.log(content)3 });
 
在1.7版之前,jQuery的Ajax操作采用回调函数。
1 $.ajax({2     url:"/echo/json/",3     success: function(response){4         console.info(response.name);5     }6 });
 
1.7版之后,Ajax操作直接返回Promise对象,这意味着可以用then方法指定回调函数。
1 $.ajax({2     url: "/echo/json/",3 }).then(function (response) {4     console.info(response.name);5 });
 
除此之外,deferred对象的第二个好处,就是它允许你自由添加多个回调函数。

1
$.ajax("test.html")2   .done(function(){ alert("哈哈,成功了!");} )3   .fail(function(){ alert("出错啦!"); } )4   .done(function(){ alert("第二个回调函数!");} );
 
deferred对象的第三个好处,就是它允许你为多个事件指定一个回调函数,这是传统写法做不到的。

1
$.when($.ajax("test1.html"), $.ajax("test2.html"))2   .done(function(){ alert("哈哈,成功了!"); })3   .fail(function(){ alert("出错啦!"); });
  这段代码的意思是,先执行两个操作$.ajax("test1.html")和$.ajax("test2.html"),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数。
 
deferred对象有多种方法可以使用,下面做一个总结:
  (1) $.Deferred() 生成一个deferred对象。
  (2) deferred.done() 指定操作成功时的回调函数
  (3) deferred.fail() 指定操作失败时的回调函数
  (4) deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口。
  (5) deferred.resolve() 手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法。
  (6)deferred.reject() 这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态变为"已失败",从而立即触发fail()方法。
  (7) $.when() 为多个操作指定回调函数。
  (8)deferred.then() 有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。
  $.when($.ajax( "/main.php" ))
  .then(successFunc, failureFunc );
如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法。如果then()只有一个参数,那么等同于done()。
  (9)deferred.always() 这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。