jQuery Deffered 对象

jQuery Deffered 对象

API DOCUMENTION: Deffered Object

阮一峰blog: jQuery的deferred对象详解


以下是官方文档的说明:

Deffered对象,从jQuery 1.5版本开始引入,是一个可链式操作的实用工具对象,可以通过调用jQuery.Deffered()方法创建。它可以将多个回调注册到回调队列中,调用回调队列,和传递成功或失败状态的任何同步或异步函数。

Deffered对象是可链式操作的,类似于其他的jQuery对象,但它有自己的特有方法。在创建一个Deffered对象之后,你可以使用下面的任何一个方法,通过直接在创建的Deffered对象上调用或者先将该对象保存入一个变量然后再在变量上调用这些方法。

(正文在下面)

deferred.always()

Add handlers to be called when the Deferred object is either resolved or rejected.

deferred.catch()

Add handlers to be called when the Deferred object is rejected.

deferred.done()

Add handlers to be called when the Deferred object is resolved.

deferred.fail()

Add handlers to be called when the Deferred object is rejected.

Also in: Deprecated > Deprecated 1.7 | Removed

deferred.isRejected()

Determine whether a Deferred object has been rejected.

Also in: Deprecated > Deprecated 1.7 | Removed

deferred.isResolved()

Determine whether a Deferred object has been resolved.

deferred.notify()

Call the progressCallbacks on a Deferred object with the given args.

deferred.notifyWith()

Call the progressCallbacks on a Deferred object with the given context and args.

Also in: Deprecated > Deprecated 1.8

deferred.pipe()

Utility method to filter and/or chain Deferreds.

deferred.progress()

Add handlers to be called when the Deferred object generates progress notifications.

deferred.promise()

Return a Deferred’s Promise object.

deferred.reject()

Reject a Deferred object and call any failCallbacks with the given args.

deferred.rejectWith()

Reject a Deferred object and call any failCallbacks with the given context and args.

deferred.resolve()

Resolve a Deferred object and call any doneCallbacks with the given args.

deferred.resolveWith()

Resolve a Deferred object and call any doneCallbacks with the given context and args.

deferred.state()

Determine the current state of a Deferred object.

deferred.then()

Add handlers to be called when the Deferred object is resolved, rejected, or still in progress.

jQuery.Deferred()

A factory function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.

Also in: Core

jQuery.when()

Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.

.promise()

Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished.


# 1 什么是deffered对象?

defer : [dɪ'fɜr] 延期;延迟

简单说,deffered对象就是jQuery的回调函数解决方案。

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

Deffered对象最常用的场景应该就是在ajax操作中了。让我们先来看看传统的ajax操作写法。

#2 ajax操作的链式写法

$.ajax({
  url: "test.html",
  success: function() {
    alert("success");
  },
  error: function() {
    alert('something wrong');
  }
});

$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,你没法进行链式操作;如果高于1.5.0版本,返回的是deferred对象,可以进行链式操作。

现在,我们可以这样写了:

$.ajax("test.html")
    .done(function(){alert("success")})
    .fail(function(){alert("something wrong")});

done相当于success方法,fail相当于error方法。

#3 允许指定多个回调函数

Deffered对象允许你自由添加多个回调函数,如下:

$.ajax("test.html")
    .done(function(){alert("success")})
    .fail(function(){alert("something wrong")})
    .done(function(){alert("another sucess")})

它们将按照添加顺序执行。

#4 Deffered对象可应用于任何操作

不局限于ajax操作,deffered对象可以应用于任何操作。

假设有如下一个耗时的例子:

var wait = function() {
  var tasks = function() {
    alert('done!');
  }
  setTimeout(tasks, 5000);
};

如果我们想为这一操作指定回调函数,可以使用$.when():

$.when(wait())
    .done(function(){alert("success")})
    .fail(function(){alert("error")});

但是,这样不行,done()方法会立即执行,起不到回调函数的作用。原因在于$.when()的参数只能是deferred对象,所以必须对wait()进行改写:

var dtd = $.Deffered(); // create a deffered object
var wait = function(dtd) {
  var tasks = function() {
    alert("done!");
    dtd.resolve(); // change the state of deffered object
  };
  setTimeout(tasks, 5000);
  return dtd;
};

现在,wait函数返回的是deffered对象,这样就可以进行链式操作了:

$.when(wait(dtd))
    .done(function() {alert("success")})
    .fail(function() {alert("error")});

#5 deffered对象的resolve()和reject()方法

现在要引入一个新概念"执行状态"。jQuery规定,deferred对象有三种执行状态----未完成,已完成和已失败。如果执行状态是"已完成"(resolved),deferred对象立刻调用done()方法指定的回调函数;如果执行状态是"已失败",调用fail()方法指定的回调函数;如果执行状态是"未完成",则继续等待,或者调用progress()方法指定的回调函数(jQuery1.7版本添加)。

调用resolve方法即可改变deffered对象的“执行状态”为”已完成“,从而触发done方法;reject方法可改变“执行状态”为”已失败“,从而触发fail方法。

#6 deffered.promise()方法

上面的写法有个问题,dtd是全局对象,所以它的执行状态可以从外部改变。

为了避免这种情况,jQuery提供了deffered.promise()方法。它的作用是,在原来的deffered对象上返回另一个deffered对象,后者只开放与改变执行状态无关的方法

看下面的例子:

var dtd = $.Deffered();
var wait = function(dtd) {
  var tasks = function() {
    alert("done!");
    dtd.resolve();
  };
  
  setTimeout(tasks, 5000);
  return dtd.promise();
};

var d = wait(dtd);
$.when(d)
    .done(function(){alert("success")})
    .fail(function(){alert("error")});
d.resolve(); // 此时,这个语句时无效的 

不过,更好的写法时将dtd对象变成wait函数的内部对象:

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

    setTimeout(tasks,5000);
    return dtd.promise(); // 返回promise对象
  };
  $.when(wait())
  .done(function(){ alert("success"); })
  .fail(function(){ alert("error"); });

#7 直接使用$.Deffered()

另一种防止执行状态被外部改变的方法是使用deffered对象的构建函数$.Deffered()。

我们直接将wait函数传入$.Deffered():

$.Deffered(wait)
    .done(function() {alert("success")})
    .fail(function() {alert("error")});

jQuery规定,jQuery.Deffered()可以接受一个函数名作为参数,jQuery.Deffered()所生成的deffered对象将作为这个函数的默认参数。

除了上面讲到的两种方法,我们还可以直接在wait对象上部署deffered接口;

var dtd = $.Deffered();
var wait = function(dtd) {
  var tasks = funciton() {
    alert("done!");
    dtd.resolve();
  };
  setTimeout(tasks, 5000);
};

dtd.promise(wait);
wait.done(function(){alert("success")})
    .fail(function(){alert("error")});
wait(dtd);

这里的关键是dtd.promise(wait)这一行,它的作用就是在wait对象上部署Deferred接口。正是因为有了这一行,后面才能直接在wait上面调用done()和fail()。

转载于:https://www.cnblogs.com/redtree/p/jquery-deffered-object.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值