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 相关文章推荐
限制文本框输入N个字符的js代码
May 13 Javascript
JS中FRAME的操作问题实例分析
Oct 21 Javascript
JavaScript数组去重的几种方法效率测试
Oct 23 Javascript
Ajax+FormData+javascript实现无刷新表单信息提交
Oct 24 Javascript
hovertree插件实现二级树形菜单(简单实用)
Dec 28 Javascript
整理关于Bootstrap排版的慕课笔记
Mar 29 Javascript
利用Three.js如何实现阴影效果实例代码
Sep 26 Javascript
浅谈Webpack 是如何加载模块的
May 24 Javascript
JS的函数调用栈stack size的计算方法
Jun 24 Javascript
vue 查看dist文件里的结构(多种方式)
Jan 17 Javascript
JavaScript 事件代理需要注意的地方
Sep 08 Javascript
如何使用vue3打造一个物料库
May 08 Vue.js
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
PHP两种快速排序算法实例
2015/02/15 PHP
PHP性能优化大全(php.ini)
2016/05/20 PHP
php-fpm服务启动脚本的方法
2018/04/27 PHP
服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu
2007/03/06 Javascript
JavaScript打开word文档的实现代码(c#)
2012/04/16 Javascript
JS中表单的使用小结
2014/01/11 Javascript
javascript自动给文本url地址增加链接的方法分享
2014/01/20 Javascript
JS实现网页上随滚动条滚动的层效果代码
2015/11/04 Javascript
js实现表单及时验证功能 用户信息立即验证
2016/09/13 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
简单实现JS计算器功能
2016/12/21 Javascript
简单实现bootstrap选项卡效果
2017/02/08 Javascript
用Node编写RESTful API接口的示例代码
2018/07/04 Javascript
jQuery的Ajax接收java返回数据方法
2018/08/11 jQuery
微信小程序实现录音时的麦克风动画效果实例
2019/05/18 Javascript
百度小程序之间的页面通信过程详解
2019/07/18 Javascript
[01:22:42]2014 DOTA2华西杯精英邀请赛 5 24 DK VS LGD
2014/05/26 DOTA
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
对于Python的Django框架使用的一些实用建议
2015/04/03 Python
用python实现的线程池实例代码
2018/01/06 Python
Python引用计数操作示例
2018/08/23 Python
python实现简易动态时钟
2018/11/19 Python
Python控制键盘鼠标pynput的详细用法
2019/01/28 Python
PyTorch里面的torch.nn.Parameter()详解
2020/01/03 Python
Python函数基本使用原理详解
2020/03/19 Python
荷兰度假屋租赁网站:Aan Zee
2020/02/28 全球购物
超市营业员求职简历的自我评价
2013/10/17 职场文书
教师岗位职责
2013/11/17 职场文书
工作自我评价分享
2013/12/01 职场文书
新郎新娘婚礼答谢词
2014/01/11 职场文书
销售员个人求职的自我评价
2014/02/10 职场文书
道路交通事故人身损害赔偿协议书
2014/11/19 职场文书
酒店前台辞职书
2015/02/26 职场文书
职位证明模板
2015/06/23 职场文书
大学宣传委员竞选稿
2015/11/19 职场文书
Redis中key的过期删除策略和内存淘汰机制
2022/04/12 Redis