jQuery 源码分析笔记(3) Deferred机制


Posted in Javascript onJune 19, 2011

Deferred把回调函数注册到一个队列中,统一管理,并且可以同步或者异步地调用这些函数。
jQuery.Deferred()用来构造一个Deferred对象。该对象有状态值,共有三种: Rejected, Resolved和初始状态。其中Resolved表示该操作成功完成了,而Rejected 则表示出现了错误,调用失败。Deferred对象的主要成员如下:
done(callback): 注册一个callback函数,当状态为resolved时被调用。 * fail(callback): 注册一个callback函数,当状态为rejected时被调用。 * always(callback): 注册一个callback函数,无论是resolved或者rejected都会被调用。 * then(successCallback, failureCallback): 同时传入成功和失败的回调函数。 * pipe(successFilter, failureFilter): 在调用成功和失败的回调函数前先调用pipe 指定的函数。算是一种管道机制,拦截了函数调用。 * resolve(args): 把状态设置为Resolved。 * reject(args): 把状态设置为Rejected。 * promse(): 返回的是一个不完整的Deferred的接口,没有resolve和reject。即不能修改Deferred对象的状态。可以看作是一种只读视图。这是为了不让外部函数提早触发回调函数。比如$.ajax在1.5版本后不再返回XMLHttpRequest,而是返回一个封装了 XMLHttpRequest和Deferred对象接口的object。其中Deferred部分就是promise()得到的,这样不让外部函数调用resolve和reject,防止在ajax完成前触发回调函数。把这两个函数的调用权限保留给ajax内部。
这个模块的代码从939行开始,紧接着jQuery对象的声明。也算是一个基础核心代码了。同时也是1.5版本最大的变化之一。
实际上Resolve和Reject的代码逻辑是一样的,只是对应的状态不同而已。为了代码复用,内部先实现了一个Deferred,然后真正的Deferred内部new了两个Deferred,一个作为 Resolve,另一个作为Reject。
_Deferred对象内部维护了一个函数数组(callback list)。Done(f1, f2...)的工作就是把这些callback依次push到这个队列中保存下来。而resolveWith(带参的resolve)和resolve依次调用这写callback函数。
Done中,需要判断事件是否已经完成。如果callback加入chain时事件已经完成,则需要马上执行callback。这个特性是让callback不用再和触发异步事件声明写在一起的原因。比如原来必须写$.post("...", function(data) { ... })。这个success callback必须写在这里,而现在可以写:

var defer = $.post("..."); 
// ... 
defer.success(function(data) { 
// ... 
}); 
// ... 
defer.fail(function(data) { 
// ... 
});

这样异步事件的声明和回调函数就可以分别管理了。这是1.5版本重写后的最大变化。
pipe(successFilter, failureFilter)函数修改了原来对象中的callback list。在两个callback list前面用then函数分别插入了Filter函数。然后返回。这样当这个Deferred对象的状态变化时,会先调用pipe函数指定的Filter函数,然后才会调用callback list。
promise()则单纯许多,就是new一个新object,然后把需要的成员copy进去。这个需要的成员定义在一个叫promiseMethods常量中。
var promiseMethods = "done fail isResolved isRejected promise then always pipe".split(" ");
Javascript 相关文章推荐
Javascript 两个窗体之间传值实现代码
Sep 25 Javascript
prototype 中文参数乱码解决方案
Nov 09 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
Nov 20 Javascript
解读JavaScript代码 var ie = !-[1,] 最短的IE判定代码
May 28 Javascript
jQuery数组处理代码详解(含实例演示)
Feb 03 Javascript
js实现登陆遮罩效果的方法
Jul 28 Javascript
js实现的万能flv网页播放器代码
Apr 30 Javascript
vue.js实例todoList项目
Jul 07 Javascript
Vue-CLI 3.X 部署项目至生产服务器的方法
Mar 22 Javascript
vue.js多页面开发环境搭建过程
Apr 24 Javascript
vue操作动画的记录animate.css实例代码
Apr 26 Javascript
JS数组reduce()方法原理及使用技巧解析
Jul 14 Javascript
jQuery 源码分析笔记(7) Queue
Jun 19 #Javascript
jQuery 源码分析笔记(5) jQuery.support
Jun 19 #Javascript
jQuery调用WebService的实现代码
Jun 19 #Javascript
非常棒的10款jQuery 幻灯片插件
Jun 14 #Javascript
在jquery中处理带有命名空间的XML数据
Jun 13 #Javascript
jquery 与NVelocity 产生冲突的解决方法
Jun 13 #Javascript
用Juery网页选项卡实现代码
Jun 13 #Javascript
You might like
实例(Smarty+FCKeditor新闻系统)
2007/01/02 PHP
PHPMailer 中文使用说明小结
2010/01/22 PHP
PHP中对用户身份认证实现两种方法
2011/06/04 PHP
ThinkPHP表单数据智能写入create方法实例分析
2015/09/27 PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
2017/11/12 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
2020/08/07 PHP
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
jquery+php随机生成红包金额数量代码分享
2015/08/27 Javascript
谈一谈js中的执行环境及作用域
2016/03/30 Javascript
AngularJS通过$sce输出html的方法
2016/09/22 Javascript
JavaScript生成验证码并实现验证功能
2016/09/24 Javascript
浅析script标签中的defer与async属性
2016/11/30 Javascript
vue2.0构建单页应用最佳实战
2017/04/01 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
原生js实现俄罗斯方块
2020/10/20 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
2021/03/02 Javascript
python ElementTree 基本读操作示例
2009/04/09 Python
python操作MySQL数据库的方法分享
2012/05/29 Python
python解析发往本机的数据包示例 (解析数据包)
2014/01/16 Python
python解析xml模块封装代码
2014/02/07 Python
python实现bucket排序算法实例分析
2015/05/04 Python
Python中将字典转换为列表的方法
2016/09/21 Python
python中文分词教程之前向最大正向匹配算法详解
2017/11/02 Python
基于Python socket的端口扫描程序实例代码
2018/02/09 Python
基于python-pptx库中文文档及使用详解
2020/02/14 Python
python多进程使用函数封装实例
2020/05/02 Python
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
购买正版游戏和游戏激活码:Green Man Gaming
2019/11/06 全球购物
小学教师听课制度
2014/02/01 职场文书
态度决定一切演讲稿
2014/05/20 职场文书
个人四风问题对照检查材料
2014/09/26 职场文书
党员组织生活会发言材料
2014/10/17 职场文书
中学图书馆工作总结
2015/08/11 职场文书
初中体育教学随笔
2015/08/15 职场文书
python分分钟绘制精美地图海报
2022/02/15 Python
CentOS7和8下安装Maven3.8.4
2022/04/07 Servers