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 相关文章推荐
js里的prototype使用示例
Nov 19 Javascript
另一个javascript小测验(代码集合)
Jul 27 Javascript
分享9点个人认为比较重要的javascript 编程技巧
Apr 27 Javascript
js实现页面跳转的五种方法推荐
Mar 10 Javascript
原生js实现class的添加和删除简单代码
Jul 12 Javascript
深入浅出讲解ES6的解构
Aug 03 Javascript
分类解析jQuery选择器
Nov 23 Javascript
vue中子组件调用兄弟组件方法
Jul 06 Javascript
vue 巧用过渡效果(小结)
Sep 22 Javascript
JS事件绑定的常用方式实例总结
Mar 02 Javascript
js 闭包深入理解与实例分析
Mar 19 Javascript
js实现飞机大战小游戏
Aug 26 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
在WAMP环境下搭建ZendDebugger php调试工具的方法
2011/07/18 PHP
PHP7中I/O模型内核剖析详解
2019/04/14 PHP
让firefox支持IE的一些方法的javascript扩展函数代码
2010/01/02 Javascript
JQuery1.6 使用方法三
2011/11/23 Javascript
javascript时区函数介绍
2012/09/14 Javascript
JS原型对象通俗"唱法"
2012/12/27 Javascript
jquery提取元素里的纯文本不包含span等里的内容
2013/09/30 Javascript
javascript定时器完整实例
2015/02/10 Javascript
常用的JavaScript WEB操作方法分享
2015/02/28 Javascript
jQuery判断多个input file 都不能为空的例子
2015/06/23 Javascript
jQuery实现自定义右键菜单的树状菜单效果
2015/09/02 Javascript
ajax实现动态下拉框示例
2017/01/10 Javascript
vue和webpack安装命令详解
2018/06/15 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
vue中$refs, $emit, $on, $once, $off的使用详解
2019/05/26 Javascript
jQuery实现form表单基于ajax无刷新提交方法实例代码
2019/11/04 jQuery
jQuery表单校验插件validator使用方法详解
2020/02/18 jQuery
[00:31]DOTA2上海特级锦标赛 Fnatic战队宣传片
2016/03/04 DOTA
python根据路径导入模块的方法
2014/09/30 Python
对Python新手编程过程中如何规避一些常见问题的建议
2015/04/01 Python
对python中Json与object转化的方法详解
2018/12/31 Python
Python图像阈值化处理及算法比对实例解析
2020/06/19 Python
python实现经典排序算法的示例代码
2021/02/07 Python
全球最大的网上自行车商店:Chain Reaction Cycles
2016/12/02 全球购物
巴西化妆品商店:Lojas Rede
2019/07/26 全球购物
三星印度官网:Samsung印度
2019/08/03 全球购物
总经理秘书工作职责
2013/12/26 职场文书
避暑山庄导游词
2015/02/04 职场文书
关于召开会议的通知
2015/04/15 职场文书
党支部意见范文
2015/06/02 职场文书
MongoDB balancer的使用详解
2021/04/30 MongoDB
Pandas自定义选项option设置
2021/07/25 Python
Python的三个重要函数详解
2022/01/18 Python
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电
windows系统安装配置nginx环境
2022/06/28 Servers
mysql拆分字符串作为查询条件的示例代码
2022/07/07 MySQL