http://www.web008.net

jQuery之Deferred对象详解,jQuery的Deferred对象概述

jQuery的Deferred对象概述

2017/03/02 · CSS

本文由 伯乐在线 - HansDo 翻译,叙帝利 校稿。未经许可,防止转载!
英语出处:Aurelio De Rosa。迎接参预翻译组。

十分久以来,JavaScript 开荒者们习贯用回调函数的章程来履行一些任务。最广大的事例就是采用 addEventListener()函数来增添贰个回调函数, 用来在钦点的风浪(如 clickkeypress卡塔 尔(英语:State of Qatar)被触发时,施行黄金年代多种的操作。回调函数轻便有效——在逻辑并不复杂的时候。缺憾的是,风流倜傥旦页面包车型大巴复杂度增加,而你因而须要实施比超多互为或串行的异步操作时,这么些回调函数会让您的代码难以维护。

ECMAScript 二零一六(又名 ECMAScript 6卡塔尔国引入了三个原生的法门来缓慢解决那类难点:promises。假若您还不了然 promise 是何等,能够阅读那篇文章《Javascript Promise概述》。jQuery 则提供了别有风味的另生机勃勃种 promises,叫做 Deferred 对象。並且 Deferred 对象的引入时间要比 ECMAScript 引进 promise 早了一些年。在这里篇作品里,作者会介绍 Deferred 对象和它希图减轻的主题素材是如何。

deferred对象是jQuery对Promises接口的完毕。它是非同步操作的通用接口,能够被当作是一个守候完毕的职责,开垦者通过有个别透过的接口对其张开设置。事实上,它扮演代理人(proxy卡塔 尔(阿拉伯语:قطر‎的角色,将那个非同步操作包装成具备某个统后生可畏本性的靶子,标准例证就是Ajax操作、网页动漫、web worker等等。

Deferred对象简史

Deferred对象是在 jQuery 1.5中引进的,该指标提供了生龙活虎多种的不二秘技,能够将八个回调函数注册进叁个回调队列里、调用回调队列,以致将一齐或异步函数推行结果的成功也许失利传递给相应的管理函数。从那今后,Deferred 对象就成了钻探的话题, 在那之中不乏商量意见,这几个视角也一向在变化莫测。一些非凡的商酌的见解如《你并从未明了 Promise 》和《论 Javascript 中的 Promise 以至 jQuery 是什么样把它搞砸的》。

Promise 对象 是和 Deferred 对象一齐作为 jQuery 对 Promise 的风度翩翩种完毕。在 jQuery1.x 和 2.x 版本中, Deferred 对象坚决守护的是《CommonJS Promises 提案》中的约定,而 ECMAScript 原生 promises 方法的成立根基《Promises/A+ 提案》也是以那黄金年代议案书为底工衍生而来。所以好似大家一齐首波及的,之所以 Deferred 对象没有如约《Promises/A+ 议案》,是因为那个时候前面一个根本还未被构想出来。

出于 jQuery 扮演的先驱的角色以至后向包容性难点,jQuery1.x 和 2.x 里 promises 的使用格局和原生 Javascript 的用法并不相仿。其他,由于 jQuery 本身在 promises 方面依据了别的生龙活虎套议事原案,那招致它不可能配合其余完成promises 的库,比如 Q library。

不过将在赶到的 jQuery 3 改进了 同原生 promises(在 ECMAScript二零一四中贯彻卡塔 尔(阿拉伯语:قطر‎的互操作性。纵然为了向后卓越,Deferred 对象的首要性形式之生龙活虎(then()卡塔 尔(阿拉伯语:قطر‎的艺术签字依然会稍稍不相同,但作为方面它曾经同 ECMAScript 二〇一六 标准越来越意气风发致。

jQuery的富有Ajax操作函数,暗许重返的正是三个deferred对象。

jQuery中的回调函数

举叁个例子来精通为什么大家需求用到 Deferred指标。使用 jQuery 时,平时会用到它的 ajax 方法试行异步的数码哀告操作。大家不要紧假如你在付出三个页面,它能够发送 ajax 须求给 GitHub API,指标是读取叁个顾客的 Repository 列表、定位到近期更新三个Repository,然后找到第一个名称叫“README.md”的公文并获得该公文的从头到尾的经过。所以据书上说以上描述,每一个央求唯有在前一步成功后工夫早前。换言之,这么些央求必需依次施行

上边的陈说能够调换来伪代码如下(注意本身用的实际不是当真的 Github API卡塔 尔(阿拉伯语:قطر‎:

JavaScript

var username = 'testuser'; var fileToSearch = 'README.md'; $.getJSON('' + username + '/repositories', function(repositories) { var lastUpdatedRepository = repositories[0].name; $.getJSON('' + username + '/repository/' + lastUpdatedRepository + '/files', function(files) { var README = null; for (var i = 0; i < files.length; i++) { if (files[i].name.indexOf(fileToSearch) >= 0) { README = files[i].path; break; } } $.getJSON('' + username + '/repository/' + lastUpdatedRepository + '/file/' + README + '/content', function(content) { console.log('The content of the file is: ' + content); }); }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var username = 'testuser';
var fileToSearch = 'README.md';
 
$.getJSON('https://api.github.com/user/' + username + '/repositories', function(repositories) {
  var lastUpdatedRepository = repositories[0].name;
 
$.getJSON('https://api.github.com/user/' + username + '/repository/' + lastUpdatedRepository + '/files', function(files) {
    var README = null;
 
for (var i = 0; i < files.length; i++) {
      if (files[i].name.indexOf(fileToSearch) >= 0) {
        README = files[i].path;
 
break;
      }
    }
 
$.getJSON('https://api.github.com/user/' + username + '/repository/' + lastUpdatedRepository + '/file/' + README + '/content', function(content) {
      console.log('The content of the file is: ' + content);
    });
  });
});

如你所见,使用回调函数的话,大家需求一再嵌套来让 ajax 乞请根据大家愿意的次第试行。现代码里涌出过多嵌套的回调函数,可能有相当多互为独立但供给将它们一同的回调时,我们反复把这种状态称作“回调鬼世界( callback hell )“。

为了多少改善一下,你可以从自个儿创设的佚名函数中领到出命名函数。但那支援并比不大,因为大家照旧在回调的火坑中,还是面临着回调嵌套和联合的难点。这个时候是 DeferredPromise对象上台的时候了。

Promises是什么

Deferred和Promise对象

Deferred 对象足以被用来实践异步操作,比如 Ajax 必要和动画片的完毕。在 jQuery 中,Promise指标是不能不由Deferred目的或 jQuery 对象创立。它富有 Deferred 对象的意气风发有个别方法:always(),done(), fail(), state()then()。大家在下生机勃勃节会讲到这么些艺术和别的细节。

假如您来自于原生 Javascript 的世界,你大概会对那七个指标的留存以为吸引:为何 jQuery 有五个对象(DeferredPromise卡塔 尔(英语:State of Qatar)而原生JS 独有二个(Promise卡塔 尔(英语:State of Qatar)? 在自己写作的书《jQuery 实践(第三版)》里有三个类比,能够用来讲解那个主题素材。

Deferred目的常常用在从异步操作再次来到结果的函数里(重临结果只怕是 error,也可能有可能为空卡塔尔——即结果的生产者函数里。而回到结果后,你不想让读取结果的函数改变Deferred 对象的场所(译者注:包罗 Resolved 拆解剖判态,Rejected 推却态卡塔 尔(阿拉伯语:قطر‎,这个时候就能够用到 promise 对象——即 Promise 对象总在异步操作结果的消费者函数里被运用。

为了理清那几个概念,大家纵然你供给实现几个依照 promise 的timeout()函数(在本文稍后会呈现这些事例的代码卡塔 尔(阿拉伯语:قطر‎。你的函数会等待钦点的生机勃勃段时间后归来(这里未有重临值),即一个生产者函数而那么些函数的附和消费者们并不留意操作的结果是马到功成(解析态 resolved卡塔 尔(阿拉伯语:قطر‎还是诉讼失败(屏绝态 rejected卡塔尔,而只关怀他们须要在 Deferred 对象的操作成功、失败,可能采用进展通告后接着实施一些其它函数。别的,你还指望能作保花费者函数不会自动拆解深入分析或拒却Deferred对象。为了达到这后生可畏对象,你必得在劳动者函数timeout()中开创 Deferred 对象,并只回去它的 Promise 对象,并非Deferred对象自己。那样一来,除了timeout()函数之外就从未人能够调用到resolve()reject()进而改换Deferred 对象的动静了。

在这个 StackOverflow 问题 里你能够明白到越来越多关于 jQuery 中 Deferred 和 Promise 对象的不及。

既是您曾经了然里那七个对象,让大家来看一下它们都富含哪些措施。

由于JavaScript单线程的特色,如若有些操作耗时相当短,其余操作就必须排队等候。为了幸免全部程序失去响应,平常的缓慢解决格局是将那几个排在前边的操作,写成“回调函数”(callback卡塔尔国的花样。那样做尽管能够消除难题,但是有生机勃勃对赫赫有名短处:

Deferred对象的章程

Deferred目的优越灵活并提供了你或者必要的兼具办法,你能够因此调用 jQuery.Deferred() 像上边相近创立它:

JavaScript

var deferred = jQuery.Deferred();

1
var deferred = jQuery.Deferred();

或者,使用 $作为 jQuery 的简写:

JavaScript

var deferred = $.Deferred();

1
var deferred = $.Deferred();

创建完 Deferred指标后,就可以动用它的一文山会海措施。处了后生可畏度被丢掉的 removed 方法外,它们是:

  • always(callbacks[, callbacks, ..., callbacks]): 增加在该 Deferred 对象被拆解解析或被驳倒时调用的管理函数
  • done(callbacks[, callbacks, ..., callbacks]): 增多在该 Deferred 对象被剖判时调用的处理函数
  • fail(callbacks[, callbacks, ..., callbacks]): 加多在该 Deferred 对象被驳回时调用的管理函数
  • notify([argument, ..., argument]):调用 Deferred 对象上的 progressCallbacks 管理函数并传递制订的参数
  • notifyWith(context[, argument, ..., argument]): 在制定的左右文中调用 progressCallbacks 管理函数并传递制定的参数。
  • progress(callbacks[, callbacks, ..., callbacks]): 增加在该 Deferred 对象产生进展公告时被调用的管理函数。
  • promise([target]): 返回 Deferred 对象的 promise 对象。
  • reject([argument, ..., argument]): 拒却三个 Deferred 对象并以钦命的参数调用全数的failCallbacks管理函数。
  • rejectWith(context[, argument, ..., argument]): 拒却三个 Deferred 对象并在内定的上下文中以钦赐参数调用全数的failCallbacks管理函数。
  • resolve([argument, ..., argument]): 拆解解析二个 Deferred 对象并以指定的参数调用全体的 doneCallbackswith 管理函数。
  • resolveWith(context[, argument, ..., argument]): 深入分析三个 Deferred 对象并在内定的上下文中以钦定参数调用全部的doneCallbacks管理函数。
  • state(): 重回当前 Deferred 对象的事态。
  • then(resolvedCallback[, rejectedCallback[, progressCallback]]): 增加在该 Deferred 对象被剖判、谢绝或收到进展通告时被调用的管理函数

从上述那写方法的叙说中,笔者想优质强调一下 jQuery 文档和 ECMAScript 规范在术语上的不及。在 ECMAScript 中, 无论一个 promise 被成功 (fulfilled) 依然被拒却 (rejected),大家都说它被深入分析 (resolved) 了。可是在 jQuery 的文书档案中,被深入分析那几个词指的是 ECMAScript 标准中的完毕(fulfilled) 状态。

由于地点列出的点子太多, 这里不可能风流倜傥风姿洒脱详述。不过在下焕发青新禧会有几个呈现 DeferredPromise用法的演示。第叁个例子中大家会选择Deferred 对象重写“ jQuery 的回调函数”那风流浪漫节的代码。第壹个例子里笔者会表明从前商量的生产者–消费者其生机勃勃比喻。

1.回调函数往往写成函数参数的款式,招致函数的输入和出口极其混乱,整个程序的可阅读性差;
2.回调函数往往只可以钦赐二个,如若有四个操作,就须求改写回调函数。
3.百分百程序的运作流程被打乱,除错和调节和测验的难度都对应扩展。

利用 Deferred 依次实践 Ajax 诉求

那焕发青新春小编会利用Deferred对象和它提供的章程使“jQuery 的回调函数”那风姿浪漫节的代码更兼具可读性。但在三头扎进代码以前,让大家先搞掌握生龙活虎件事:在 Deferred 对象共处的不二秘诀中,我们需求的是怎么。

依据大家的须要及上文的点子列表,很显明我们不只能够用 done()也足以通过 then()来管理操作成功的情形,思量到许四个人早已习贯了采纳JS 的原生 Promise指标,这么些示例里自身会用 then()方式来贯彻。要专一 then()done()这两个之间的叁个主要不同是 then()能够把收到到的值通过参数传递给后续的 then(),done(),fail()progress()调用。

由此最终大家的代码应该像上面那样:

JavaScript

var username = 'testuser'; var fileToSearch = 'README.md'; $.getJSON('' + username + '/repositories') .then(function(repositories) { return repositories[0].name; }) .then(function(lastUpdatedRepository) { return $.getJSON('' + username + '/repository/' + lastUpdatedRepository + '/files'); }) .then(function(files) { var README = null; for (var i = 0; i < files.length; i++) { if (files[i].name.indexOf(fileToSearch) >= 0) { README = files[i].path; break; } } return README; }) .then(function(README) { return $.getJSON('' + username + '/repository/' + lastUpdatedRepository + '/file/' + README + '/content'); }) .then(function(content) { console.log(content); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var username = 'testuser';
var fileToSearch = 'README.md';
 
$.getJSON('https://api.github.com/user/' + username + '/repositories')
  .then(function(repositories) {
    return repositories[0].name;
  })
  .then(function(lastUpdatedRepository) {
    return $.getJSON('https://api.github.com/user/' + username + '/repository/' + lastUpdatedRepository + '/files');
  })
  .then(function(files) {
    var README = null;
 
for (var i = 0; i < files.length; i++) {
      if (files[i].name.indexOf(fileToSearch) >= 0) {
        README = files[i].path;
 
break;
      }
    }
 
return README;
  })
  .then(function(README) {
    return $.getJSON('https://api.github.com/user/' + username + '/repository/' + lastUpdatedRepository + '/file/' + README + '/content');
  })
  .then(function(content) {
    console.log(content);
  });

如你所见,由于我们能够把全数操作拆分成同在叁个缩进层级的相继步骤,这段代码的可读性已经明确加强了。

Promises正是为着缓慢解决这个难点而提议的,它的重大指标就是顶替回调函数,成为非同步操作的解决方案。它的核激情想就是让非同步操作再次来到三个指标,其余操作都指向那个指标来完成。举例,假定ajax操作重返二个Promise对象。

制造二个基于 Promise 的 setTimeout 函数

您恐怕曾经通晓 setTimeout() 函数能够在延迟二个加以的年月后举行某个回调函数,只要您把日子和回调函数作为参数字传送给它。假如你想要留意气风发秒钟后在调节台打印一条日志消息,你能够用它那样写:

JavaScript

setTimeout( function() { console.log('等待了1秒钟!'); }, 1000 );

1
2
3
4
5
6
setTimeout(
  function() {
    console.log('等待了1秒钟!');
  },
  1000
);

如您所见,setTimeout的率先个参数是要试行的回调函数,第一个参数是以飞秒为单位的等候时间。那些函数数年来说运维杰出,但假使前不久您必要在 Deferred目的的点子链中引进后生可畏段时间的延时该咋办吗?

上面包车型大巴代码呈现了什么样用 jQuery 提供的 Promise目标创设叁个基于 promise 的 setTimeout(). 为了达到大家的目标,这里运用了 Deferred对象的 promise()方法。

代码如下:

JavaScript

function timeout(milliseconds) { //创造三个新Deferred var deferred = $.Deferred(); // 在钦定的飞秒数之后分析Deferred对象 set提姆eout(deferred.resolve, milliseconds); // 再次来到Deferred对象的Promise对象 return deferred.promise(); } timeout(1000).then(function() { console.log('等待了1分钟!'); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function timeout(milliseconds) {
  //创建一个新Deferred
  var deferred = $.Deferred();
 
// 在指定的毫秒数之后解析Deferred对象
  setTimeout(deferred.resolve, milliseconds);
 
// 返回Deferred对象的Promise对象
  return deferred.promise();
}
 
timeout(1000).then(function() {
  console.log('等待了1秒钟!');
});

这段代码里定义了叁个名称叫 timeout()的函数,它包裹在 JS 原生的 setTimeout()函数之外。

timeout()里, 创立了多个 Deferred对象来得以完结在延迟钦命的阿秒数之后将 Deferred 对象分析(Resolve卡塔 尔(阿拉伯语:قطر‎的效率。这里 timeout()函数是值的生产者,因而它承当创造 Deferred指标并回到 Promise对象。那样一来调用者(开销者卡塔尔国就不能够再自由深入分析或拒却 Deferred 对象。事实上,调用者只可以通过 done()fail()这么的不二等秘书诀来增添值重回时要试行的函数。

复制代码 代码如下:

jQuery 1.x/2.x同 jQuery3 的区别

在首先个例子里,我们应用 Deferred目的来查找名字包涵“README.md”的文件, 但并不曾思虑文件找不到的情形。这种处境可以被作为是操作失利,而当操作失利时,我们只怕需求暂停调用链的推行并直接跳到程序结尾。很自然地,为了落到实处那些目标,大家应有在找不到文件时抛出三个老大,并用 fail()函数来捕获它,好似 Javascriopt 的 catch()的用法同样。

在信守 Promises/A 和 Promises/A+ 的Curry(比方jQuery 3.x卡塔 尔(英语:State of Qatar),抛出的十三分会被转换到一个拒绝操作 (rejection),进而通过 fail()艺术加多的失利条件回调函数会被执行,且抛出的那一个会作为参数字传送给那个函数。

在 jQuery 1.x 和 2.x中, 未有被破获的特别会停顿程序的试行。那五个本子允许抛出的特别向上冒泡,平日最终会达到 window.onerror。而黄金时代旦未有定义异常的处理程序,格外新闻就能被出示,同时程序也会结束运营。

为了越来越好的精通那风姿罗曼蒂克行为上的区别,让大家看一下从笔者书里摘出来的这豆蔻梢头段代码:

JavaScript

var deferred = $.Deferred(); deferred .then(function() { throw new Error('一条错误音信'); }) .then( function() { console.log('第一个成功条件函数'); }, function() { console.log('第三个停业条件函数'); } ) .then( function() { console.log('第贰个成功条件函数'); }, function() { console.log('第4个停业条件函数'); } ); deferred.resolve();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var deferred = $.Deferred();
deferred
  .then(function() {
    throw new Error('一条错误信息');
  })
  .then(
    function() {
      console.log('第一个成功条件函数');
    },
    function() {
      console.log('第一个失败条件函数');
    }
  )
  .then(
    function() {
      console.log('第二个成功条件函数');
    },
    function() {
      console.log('第二个失败条件函数');
    }
  );
 
deferred.resolve();

jQuery 3.x 中, 这段代码会在决定台出口“第二个倒闭条件函数” 和 “第三个成功条件函数”。原因就好像本人后边提到的,抛出十三分后的气象会被转变来拒却操作从而退步条件回调函数一定会被实施。其他,生龙活虎旦这多少个被管理(在这里个事例里被波折条件回调函数传给了第三个then()),前边的中标条件函数就能够被实施(这里是第七个 then()里的打响条件函数卡塔 尔(英语:State of Qatar)。

在 jQuery 1.x 和 2.x 中,除了第八个函数(抛出荒唐特别的不得了卡塔尔国之外未有其他函数会被施行,所以你只会在调控台里见到“未管理的卓殊:一条错误音讯。”

你能够到下边三个JSBin链接中查看它们的举行结果的例外:

  • jQuery 1.x/2.x
  • jQuery 3

为了越来越好的精雕细琢它同 ECMAScript二零一六 的包容性,jQuery3.x 还给 DeferredPromise对象增添了叁个叫做 catch()的新格局。它能够用来定义当 Deferred对象被拒绝或 Promise对象处于拒却态时的处理函数。它的函数具名如下:

JavaScript

deferred.catch(rejectedCallback)

1
deferred.catch(rejectedCallback)

能够看来,那个艺术可是是 then(null, rejectedCallback)的三个急速格局罢了。

var promise = get('');

总结

那篇文章里笔者介绍了 jQuery 达成的 promises。Promises 让我们能够抽身这些用来合作异步函数的令人抓狂的技术,相同的时候幸免大家陷入深档期的顺序的回调嵌套之中。

而外展现一些示范,我还介绍了 jQuery 3 在同原生 promises 互操作性上所做的修改。固然大家重申了 jQuery 的老版本同ECMAScript二零一五 在 Promises 完毕上有好些个两样,Deferred对象仍是你工具箱里大器晚成件强有力的工具。作为一个专门的学问开辟职员,当项目标复杂度扩展时,你会意识它总能派上用途。

打赏扶持自身翻译更加多好文章,多谢!

打赏译者

然后,Promise对象有二个then方法,能够用来钦定回调函数。生机勃勃旦非同步操作完结,就调用钦定的回调函数。

打赏帮助自个儿翻译越多好随笔,多谢!

任选大器晚成种支付办法

图片 1 图片 2

1 赞 5 收藏 评论

复制代码 代码如下:

关于作者:HansDo

图片 3

游走于Web前后端,一向在野路子上研究着。对壁画和数学心有余而力不足(・-・*),尽其所能做多少个劳动者。 个人主页 · 笔者的篇章 · 18 ·    

图片 4

promise.then(function (content) {
  console.log(content)
})

能够将上面两段代码合并起来,那样程序的流水生产线看得更领悟。

复制代码 代码如下:

get(' (content) {
  console.log(content)
})

在1.7版以前,jQuery的Ajax操作使用回调函数。

复制代码 代码如下:

$.ajax({
    url:"/echo/json/",
    success: function(response)
    {
       console.info(response.name);
    }
});

1.7版之后,Ajax操作直接回到Promise对象,那意味能够用then方法钦点回调函数。

复制代码 代码如下:

$.ajax({
    url: "/echo/json/",
}).then(function (response) {
    console.info(response.name);
});

deferred对象的不二等秘书诀

$.deferred()方法

效用是生成一个deferred对象。

复制代码 代码如下:

var deferred = $.deferred();

done() 和 fail()

那八个点子都用来绑定回调函数。done()钦点非同步操作成功后的回调函数,fail()内定退步后的回调函数。

复制代码 代码如下:

var deferred = $.Deferred();
deferred.done(function(value) {
   alert(value);
});

它们再次来到的是本来的deferred对象,由此得以选拔链式写法,在后头再链接其余主意(满含done和fail在内卡塔尔。

resolve() 和 reject()

那七个艺术用来改换deferred对象的图景。resolve()将景况改为非同步操作成功,reject()改为操作失利。

复制代码 代码如下:

var deferred = $.Deferred();
deferred.done(function(value) {
   alert(value);
});
deferred.resolve("hello world");

万豆蔻梢头调用resolve(),就能挨个实践done()和then()方法内定的回调函数;生机勃勃旦调用reject(),就能够挨个实践fail()和then()方法钦定的回调函数。

state方法

该情势用来回到deferred对象近期的情状。

复制代码 代码如下:

var deferred = new $.Deferred();
deferred.state();  // "pending"
deferred.resolve();
deferred.state();  // "resolved"

该方法的重临值有多个:

1.pending:表示操作还一直不完毕。
2.resolved:表示操作成功。
3.rejected:表示操作失败。

notify() 和 progress()

progress()用来钦点一个回调函数,当调用notify()方法时,该回调函数将履行。它的筹算是提供一个接口,使得在非同步操作推行进度中,能够实践有个别操作,举例按期再次回到进程条的快慢。

复制代码 代码如下:

 var userProgress = $.Deferred();
    var $profileFields = $("input");
    var totalFields = $profileFields.length
    userProgress.progress(function (filledFields) {
        var pctComplete = (filledFields/totalFields)*100;
        $("#progress").html(pctComplete.toFixed(0));
    });
    userProgress.done(function () {
        $("#thanks").html("Thanks for completing your profile!").show();
    });
    $("input").on("change", function () {
        var filledFields = $profileFields.filter("[value!='']").length;
        userProgress.notify(filledFields);
        if (filledFields == totalFields) {
            userProgress.resolve();
        }
    });

then()

then()的职能也是点名回调函数,它可以承担四个参数,也正是两个回调函数。第二个参数是resolve时调用的回调函数,第3个参数是reject时调用的回调函数,第两个参数是progress()方法调用的回调函数。

复制代码 代码如下:

deferred.then( doneFilter [, failFilter ] [, progressFilter ] )

在jQuery 1.8在此以前,then()只是.done().fail()写法的语法糖,三种写法是等价的。在jQuery 1.8过后,then()重回二个新的deferred对象,而done()重返的是原来的deferred对象。若是then()内定的回调函数有重返值,该再次来到值会作为参数,传入前面包车型大巴回调函数。

复制代码 代码如下:

var defer = jQuery.Deferred();
defer.done(function(a,b){
            return a * b;
}).done(function( result ) {
            console.log("result = " + result);
}).then(function( a, b ) {
            return a * b;
}).done(function( result ) {
            console.log("result = " + result);
}).then(function( a, b ) {
            return a * b;
}).done(function( result ) {
            console.log("result = " + result);
});
defer.resolve( 2, 3 );

在jQuery 1.8版本此前,上边代码的结果是:

复制代码 代码如下:

result = 2
result = 2
result = 2

在jQuery 1.8版本之后,重返结果是

复制代码 代码如下:

result = 2
result = 6
result = NaN

这点亟待专门引起注意。

复制代码 代码如下:

$.ajax( url1, { dataType: "json" } )
.then(function( data ) {
    return $.ajax( url2, { data: { user: data.userId } } );
}).done(function( data ) {
  // 从url2赢得的多少
});

郑重声明:本文版权归美高梅163888所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。