前言:

前一篇文章中重点总结了一下then方法,它主要用来处理多个异步任务按顺序执行,即前一个任务处理完了,再继续下一个,以此类推;

而这一章节jQuery.when方法也是处理多个异步任务,它把多个异步任务(Promise对象)合并为一个Promise对象,这个合并后的Promise对象

到底是如何来更新它的状态,即何时执行,拒绝?让我们继续往下看吧!

jQuery回调、递延对象总结篇索引:

jQuery回调、递延对象总结(上篇)—— jQuery.Callbacks

jQuery回调、递延对象总结(中篇) —— 神奇的then方法

jQuery回调、递延对象总结(下篇) —— 解密jQuery.when方法

设计思路(意图)

执行jQuery.when将会返回一个Promise对象,我们称作由when生成的Promise对象,如果给定的所有Promise对象均已执行,就立即执行

由when方法产生的Promise对象,如果给定的Promise对象中有任意一个被拒绝,就立即拒绝由when生成的Promise对象,这样做的意图

好像就是为了解决这样一种需求:在指定的多个异步事件都完成了,然后才能干自己想干的事情

源码解析

jQuery.extend({
// Deferred helper
// 参数为Promise对象,我们称作:给定的Promise对象
// when函数内部的deferred对象,我们称作:由when生成的Promise对象
when: function( subordinate /* , ..., subordinateN */ ) {
var i = 0,
resolveValues = core_slice.call( arguments ),
length = resolveValues.length,
// the count of uncompleted subordinates
// 用来存储给定的未执行(解决)的Promise对象的个数
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
// 我们称deferred为when生成的Promise对象
deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values
updateFunc = function( i, contexts, values ) {
return function( value ) {
contexts[ i ] = this;
values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
// 如果给定的任意一个Promise对象未执行或拒绝,则通知由when生成的Promise对象为pending状态
// 注:contexts是由所有给定的Promise对象组成的数组,
// values是由处理所有给定的Promise对象的回调的参数组成的数组
if( values === progressValues ) {
deferred.notifyWith( contexts, values );
}
// 如果给定的Promise对象已执行(解决),且当未执行的Promise对象个数为0,
// 即:给定的所有Promise对象都已执行(解决),则立即执行由when生成的Promise对象
// 注:contexts是由所有给定的Promise对象组成的数组,
// values是由处理所有给定的Promise对象的回调的参数组成的数组(请看实例1)
else if ( !( --remaining ) ) {
deferred.resolveWith( contexts, values );
}
};
}, progressValues, progressContexts, resolveContexts; // add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length ); // resolveValues = core_slice.call( arguments ) // 别忘了最上面的这行代码
resolveContexts = new Array( length );
for ( ; i < length; i++ ) {
// 如果给定when的参数是一个Promise对象,则通知由when生成的Promise对象,通知什么,如何通知?
// 如果给定的Promise对象已执行,则执行由when生成的Promise对象(要等到所有给定Promise对象全部执行)
// 如果给定的任意一个Promise对象已拒绝,则拒绝由when生成的Promise对象
// 如果未执行或拒绝,默认是pending状态
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
resolveValues[ i ].promise()
.done( updateFunc( i, resolveContexts, resolveValues ) )
.fail( deferred.reject )
.progress( updateFunc( i, progressContexts, progressValues ) );
}
// 如果给定的不是一个Promise对象,那么负责减一
else {
--remaining;
}
}
} // if we're not waiting on anything, resolve the master
// 如果传递给when的参数都不是递延对象,则执行由when生成的Promise对象
if ( !remaining ) {
// resolveContexts为一个空数组new Array( length ),resolveValues是由when参数组成的一个数组
deferred.resolveWith( resolveContexts, resolveValues );
} return deferred.promise();
}
});

实例:关于执行由when生成的Promise对象的参数的问题

var promiseA = $.Deferred();
var promiseB = $.Deferred(); var doneFn = function(arg){
console.log(arg);
}; promiseA.done(doneFn);
promiseB.done(doneFn); promiseA.resolve('A'); // 'A'
promiseB.resolve('B'); // 'B' var whenFn = function(arg1, arg2){
console.log(this[0] === promiseA.promise()); // true
console.log(this[1] === promiseB.promise()); // true
console.log('promise' + arg1 + ', promise' + arg2 + ' All done!');
};
var whenPromise = jQuery.when(promiseA, promiseB);
whenPromise.done(whenFn); // true true 'promiseA, promiseB All done!'

jQuery回调、递延对象总结:

递延对象中的then方法作用于使多个异步任务按照顺序执行,而jQuery.when方法作用于在多个并发的异步任务执行完毕后再干自己感兴趣的事情;

jQuery递延对象是基于jQuery回调对象架构的,如果你想熟练掌握jQuery递延对象,请先移步jQuery.Callbacks对象

PS: 如有描述错误,请帮忙指正,如果你们有不明白的地方也可以发邮件给我,

  如需转载,请附上本文地址及出处:博客园华子yjh,谢谢!

jQuery回调、递延对象总结(下篇) —— 解密jQuery.when方法的更多相关文章

  1. jQuery - 01. jQuery特点、如何使用jQuery、jQuery入口函数、jQuery和DOM对象的区别、jQuery选择器、

    this指的是原生js的DOM对象 .css(“”):只写一个值是取值,写俩值是赋值 window.onload   ===   $(document).ready(); $(“”):获取元素   标 ...

  2. jQuery回调、递延对象总结(中篇) —— 神奇的then方法

    前言: 什么叫做递延对象,生成一个递延对象只需调用jQuery.Deferred函数,deferred这个单词译为延期,推迟,即延迟的意思,那么在jQuery中 又是如何表达延迟的呢,从递延对象中的t ...

  3. jQuery回调、递延对象总结(上篇)—— jQuery.Callbacks

    前言: 作为参数传递给另一个函数执行的函数我们称为回调函数,那么该回调又是否是异步的呢,何谓异步,如:作为事件处理器,或作为参数传递给 (setTimeout,setInterval)这样的异步函数, ...

  4. jQuery回调、递延对象总结

    jQuery回调.递延对象总结(上篇)—— jQuery.Callbacks jQuery回调.递延对象总结(中篇) —— 神奇的then方法 jQuery回调.递延对象总结(下篇) —— 解密jQu ...

  5. jQuery回调、递延对象总结(一)jQuery.Callbacks详解

    前言: 作为参数传递给另一个函数执行的函数我们称为回调函数,那么该回调又是否是异步的呢,何谓异步,如:作为事件处理器,或作为参数传递给 (setTimeout,setInterval)这样的异步函数, ...

  6. jQuery的deferred对象详解 jquery回调函数

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html jQuery的 ...

  7. 解密jQuery内核 Sizzle引擎筛选器 - 位置伪类(一)

    本章开始分析过滤器,根据API的顺序来 主要涉及的知识点 jQuery的组成 pushStack方法的作用 sizzle伪类选择器 首页我们知道jQuery对象是一个数组对象 内部结构 jQuery的 ...

  8. 解密jQuery事件核心 - 绑定设计(一)

    说起jQuery的事件,不得不提一下Dean Edwards大神 addEvent库,很多流行的类库的基本思想从他那儿借来的 jQuery的事件处理机制吸取了JavaScript专家Dean Edwa ...

  9. 解密jQuery事件核心 - 委托设计(二)

    第一篇 http://www.cnblogs.com/aaronjs/p/3444874.html 从上章就能得出几个信息: 事件信息都存储在数据缓存中 对于没有特殊事件特有监听方法和普通事件都用ad ...

随机推荐

  1. jdbc实现事务

    //conn需要自己获取,这里我用的时springjdbcTemplate Connection conn = null; PreparedStatement pstm = null; try { c ...

  2. asp.net使用signalr实现集群集群下面的消息推送

    1.选用Signalr的原因 Signalr内部给我们做了很多封装.当服务器或者浏览器不支持websoket协议的时候就使用长连接方式  不支持长连接再选用轮询的方式获取消息 websoket:与服务 ...

  3. Oracle 数据类型

    类型 含义 CHAR(length) 存储固定长度的字符串.参数length指定了长度,如果存储的字符串长度小于length,用空格填充.默认长度是1,最长不超过2000字节. VARCHAR2(le ...

  4. centos7安装mplayer 错误集锦

    (1)在 linux下运行程序时,发现了error while loading shared libraries这种错误,一时间不知道解决办法,在网上搜索,终于解决了:./tests: error w ...

  5. HDU 1166 敌兵布阵(线段树模板题)

    题目链接: 传送门 敌兵布阵 Time Limit: 2000MS     Memory Limit: 32768 K Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头 ...

  6. K米APP----案例分析

    K米APP----案例分析 第一部分 调研,评测 第一次上手体验 软件的美工做得不错,功能排版很清楚,用户很容易上手,不至于用户不知道怎么用这个APP点歌 软件最主要的功能是KTV的点歌功能,这个功能 ...

  7. Android中的Binder机制的简要理解

    转载自:http://www.linuxidc.com/Linux/2012-07/66195.htm http://blog.csdn.net/sunxingzhesunjinbiao/articl ...

  8. excel2013添加坐标轴名称label

    图画好了,x.y轴没有名称,怎么办那 点击左上角有个---添加图标元素----里面有轴标题应该就是

  9. SQL Server 2012 学习笔记2

    1. 新建数据库 可以在对应目录下右键新建数据库,也可以用程序添加: 先打开程序编辑对话框"New Query" create database Library 2. 添加表格 可 ...

  10. WinForm------TreeList属性介绍

    转载: http://blog.csdn.net/fwj380891124/article/details/6888077 treeList1.LookAndFeel.UseWindowsXPThem ...