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 相关文章推荐
contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
Sep 13 Javascript
js setTimeout 常见问题小结
Aug 13 Javascript
javascript中的nextSibling使用陷(da)阱(keng)
May 05 Javascript
jquery选择器需要注意的问题
Nov 26 Javascript
javascript 动态修改css样式方法汇总(四种方法)
Aug 27 Javascript
js实现对table的增加行和删除行的操作方法
Oct 13 Javascript
Node.js dgram模块实现UDP通信示例代码
Sep 26 Javascript
jquery 通过ajax请求获取后台数据显示在表格上的方法
Aug 08 jQuery
Vue起步(无cli)的啊教程详解
Apr 11 Javascript
vue element 中的table动态渲染实现(动态表头)
Nov 21 Javascript
微信分享invalid signature签名错误踩过的坑
Apr 11 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
Aug 18 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
Discuz Uchome ajaxpost小技巧
2011/01/04 PHP
thinkphp3.x连接mysql数据库的方法(具体操作步骤)
2016/05/19 PHP
图片自动更新(说明)
2006/10/02 Javascript
jQuery 1.0.4 - New Wave Javascript(js源文件)
2007/01/15 Javascript
JavaScript入门教程(3) js面向对象
2009/01/31 Javascript
基于jquery的拖动布局插件
2011/11/25 Javascript
JavaScript 产生不重复的随机数三种实现思路
2012/12/13 Javascript
关于extjs treepanel复选框选中父节点与子节点的问题
2013/04/02 Javascript
将字符串中由空格隔开的每个单词首字母大写
2014/04/06 Javascript
把文本中的URL地址转换为可点击链接的JavaScript、PHP自定义函数
2014/07/29 Javascript
js 通过cookie实现刷新不变化树形菜单
2014/10/30 Javascript
jQuery中[attribute]选择器用法实例
2014/12/31 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
JS实现跟随鼠标的链接文字提示框效果
2015/08/06 Javascript
浅析angularJS中的ui-router和ng-grid模块
2016/05/20 Javascript
js 获取本地文件及目录的方法(推荐)
2016/11/10 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
extjs简介_动力节点Java学院整理
2017/07/17 Javascript
基于JavaScript实现评论框展开和隐藏功能
2017/08/25 Javascript
AngularJS路由删除#符号解决的办法
2017/09/28 Javascript
Thinkjs3新手入门之添加一个新的页面
2017/12/06 Javascript
javascript代码优化的8点总结
2018/01/29 Javascript
JS实现的抛物线运动效果示例
2018/01/30 Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
2018/09/25 Javascript
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
基于jupyter代码无法在pycharm中运行的解决方法
2020/04/21 Python
详解如何在css中引入自定义字体(font-face)
2018/05/17 HTML / CSS
美国求婚钻戒网站:Super Jeweler
2016/08/27 全球购物
乐高瑞士官方商店:LEGO CH
2020/08/16 全球购物
如何删除一个表里面的重复行
2013/07/13 面试题
体育教育毕业生自荐信
2014/06/29 职场文书
2015年财务工作总结范文
2015/03/31 职场文书
一百条裙子读书笔记
2015/07/01 职场文书
详解TS数字分隔符和更严格的类属性检查
2021/05/06 Javascript
动漫APP软件排行榜前十名,半次元上榜,第一款由腾讯公司推出
2022/03/18 杂记