前言:

前一篇文章中重点总结了一下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. AutoIt3(AU3)开发的装机小工具,实现快速检测以及一些重用快捷操作功能

    项目相关地址 源码:https://github.com/easonjim/Installed_Tools bug提交:https://github.com/easonjim/Installed_To ...

  2. Adding New Functions to MySQL(User-Defined Function Interface UDF、Native Function)

    catalog . How to Add New Functions to MySQL . Features of the User-Defined Function Interface . User ...

  3. ecshop /includes/lib_base.php、/includes/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php Backdoor Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 ECShop是国内一款流行的网店管理系统软件,其2.7.3版本某个补丁存 ...

  4. Discuz! X upgrade/converter GETSHELL Vulnerability Via /convert/include/global.func.php Inject Special Symbol Into /convert/data/config.inc.php

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 对于PHP应用来说,处于用户的输入并正确划定"数据-代码"边界 ...

  5. FUSE 简介

    编译别人改过的一个 OpenWRT ,发现用到了一个叫 FUSE 的包.感兴趣了解一下. FUSE 是 Filesystem in USErspace 的简称.对于文件系统,经常安装系统.格式化 U ...

  6. Redis 学习笔记续

    Redis - 数据类型 Redis支持5种类型的数据类型,它描述如下的: 字符串 Redis字符串是字节序列.Redis字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你 ...

  7. 常见linux命令释义(第六天)——shell环境变量

    太懒了,这几天好像得了懒癌,一点都不想写博客.后来想想,知识嘛,还是分享出来的好.第一治自己的懒癌:第二顺便巩固下自己的知识. Linux的变量分为两种,一种是系统变量,是系统一经启动,就写进内存中的 ...

  8. bootstrap学习总结-01 环境准备

    1 下载Bootstrap Bootstrap 是最受欢迎的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB 项目.当前下载的Bootstrap版本为v3.3.7 htt ...

  9. JS-节点属性(常用!)

    (开始很生疏,不想看的知识点,后来DOM中用的特别多,才发现很重要.还有几个点,是比较容易忽略的,值得注意!) <!DOCTYPE html><html> <head&g ...

  10. js013-事件

    js013-事件 本章内容 理解事件流 使用时间处理程序 不同的事件类型 JS与HTML之间的交互是通过实践实现的.时间就还文档或浏览器窗口发生的一些特定的交互 瞬间.可以使用侦听器来预定事件,以便时 ...