jQuery回调、递延对象总结(下篇) —— 解密jQuery.when方法
前言:
前一篇文章中重点总结了一下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: 如有描述错误,请帮忙指正,如果你们有不明白的地方也可以发邮件给我,
jQuery回调、递延对象总结(下篇) —— 解密jQuery.when方法的更多相关文章
- jQuery - 01. jQuery特点、如何使用jQuery、jQuery入口函数、jQuery和DOM对象的区别、jQuery选择器、
this指的是原生js的DOM对象 .css(“”):只写一个值是取值,写俩值是赋值 window.onload === $(document).ready(); $(“”):获取元素 标 ...
- jQuery回调、递延对象总结(中篇) —— 神奇的then方法
前言: 什么叫做递延对象,生成一个递延对象只需调用jQuery.Deferred函数,deferred这个单词译为延期,推迟,即延迟的意思,那么在jQuery中 又是如何表达延迟的呢,从递延对象中的t ...
- jQuery回调、递延对象总结(上篇)—— jQuery.Callbacks
前言: 作为参数传递给另一个函数执行的函数我们称为回调函数,那么该回调又是否是异步的呢,何谓异步,如:作为事件处理器,或作为参数传递给 (setTimeout,setInterval)这样的异步函数, ...
- jQuery回调、递延对象总结
jQuery回调.递延对象总结(上篇)—— jQuery.Callbacks jQuery回调.递延对象总结(中篇) —— 神奇的then方法 jQuery回调.递延对象总结(下篇) —— 解密jQu ...
- jQuery回调、递延对象总结(一)jQuery.Callbacks详解
前言: 作为参数传递给另一个函数执行的函数我们称为回调函数,那么该回调又是否是异步的呢,何谓异步,如:作为事件处理器,或作为参数传递给 (setTimeout,setInterval)这样的异步函数, ...
- jQuery的deferred对象详解 jquery回调函数
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html jQuery的 ...
- 解密jQuery内核 Sizzle引擎筛选器 - 位置伪类(一)
本章开始分析过滤器,根据API的顺序来 主要涉及的知识点 jQuery的组成 pushStack方法的作用 sizzle伪类选择器 首页我们知道jQuery对象是一个数组对象 内部结构 jQuery的 ...
- 解密jQuery事件核心 - 绑定设计(一)
说起jQuery的事件,不得不提一下Dean Edwards大神 addEvent库,很多流行的类库的基本思想从他那儿借来的 jQuery的事件处理机制吸取了JavaScript专家Dean Edwa ...
- 解密jQuery事件核心 - 委托设计(二)
第一篇 http://www.cnblogs.com/aaronjs/p/3444874.html 从上章就能得出几个信息: 事件信息都存储在数据缓存中 对于没有特殊事件特有监听方法和普通事件都用ad ...
随机推荐
- linux永久更改eth0的ip地址
linux中永久修改ip和子网掩码,可以用命令也可以直接到文件里修改.这里推荐直接到文件中修改.1.进入网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-e ...
- git实习笔记
一.查找文件目录 二.添加上传文件 三.提交文件,描述信息 四.登录
- sublime text3 --前端工程师必备神器
sublime text3 --前端工程师必备神器 导读目录: 下载与Emmet插件安装 sublime text3 中cssrem安装与使用 sublime Text 3的中文文件名显示为方框的问题 ...
- JAVA内存机制
Java程序运行时,数据会分区存放,JavaStack(Java栈). heap(堆).method(方法区). 一.JVM内存模型 1.Java栈Java栈的区域很小,只有1M,特点是存取速度很快, ...
- 手写控件,frame,center和bounds属性
一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View ...
- wamp环境PHP安装mongodb扩展
特别注意 :本地的下载的mongo 为线性TS *86 而不是64 按照apache的版本来定.
- dos命令复制当天生成的以日期为文件名的文件
1.利用SqlServer的自动备份功能,将数据自动备份,备份出的文件格式如下: db_backup_201001270930.bak 2.编辑bat脚本 ...
- js 对象属性复制到另一个对象
var obj={a:1,b:2,c:3} var newObj={};for(var i in obj){newObj[i]=obj[i];}console.log(newObj);
- UDP 网络通信 C#
接收端 using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Thre ...
- Linux学习笔记(二)2015.4.14
笔记2.1 Q:登陆命令 A:刚开始登陆的是安装Linux时设置的普通用户,如lin,输入su - root后,成为root用户 笔记2.2 Q:切换控制台 A:ctrl+alt+F1-F7可以切 ...