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 相关文章推荐
$.ajax返回的JSON无法执行success的解决方法
Sep 09 Javascript
Ext修改GridPanel数据和字体颜色、css属性等
Jun 13 Javascript
Javascript删除指定元素节点的方法
Jun 21 Javascript
[原创]jQuery常用的4种加载方式分析
Jul 25 Javascript
JS图片左右无缝隙滚动的实现(兼容IE,Firefox 遵循W3C标准)
Sep 23 Javascript
基于javascript实现的快速排序
Dec 02 Javascript
详解JS中的this、apply、call、bind(经典面试题)
Sep 19 Javascript
详解组件库的webpack构建速度优化
Jun 18 Javascript
JS实现简单的星期格式转换功能示例
Jul 23 Javascript
使用Angular Cli如何创建Angular私有库详解
Jan 30 Javascript
微信小程序基于picker实现级联菜单
Feb 15 Javascript
vue2 拖动排序 vuedraggable组件的实现
Aug 08 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
解析PHP正则提取或替换img标记属性
2013/06/26 PHP
php实现的验证码文件类实例
2015/06/18 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
2020/05/02 PHP
巧妙破除网页右键禁用的十大绝招
2006/08/12 Javascript
jQuery+ajax实现顶一下,踩一下效果
2010/07/17 Javascript
基于jQuery的获取标签名的代码
2012/07/16 Javascript
javascript解决innerText浏览器兼容问题思路代码
2013/05/17 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
Javascript合并表格中具有相同内容单元格示例
2013/08/11 Javascript
JavaScript中使用Math.floor()方法对数字取整
2015/06/15 Javascript
JS与Ajax Get和Post在使用上的区别实例详解
2016/06/08 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
2016/06/23 Javascript
js仿百度音乐全选操作
2017/01/13 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
微信小程序开发中的疑问解答汇总
2017/07/03 Javascript
jQuery实现菜单栏导航效果
2017/08/15 jQuery
Element-UI中Upload上传文件前端缓存处理示例
2019/02/21 Javascript
微信小程序3种位置API的使用方法详解
2019/08/05 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
2020/07/11 Javascript
javascript实现点击产生随机图形
2021/01/25 Javascript
Python读写docx文件的方法
2018/05/08 Python
使用python自动追踪你的快递(物流推送邮箱)
2020/03/17 Python
Python ini文件常用操作方法解析
2020/04/26 Python
python3:excel操作之读取数据并返回字典 + 写入的案例
2020/09/01 Python
Python实现AES加密,解密的两种方法
2020/10/03 Python
Python调用Redis的示例代码
2020/11/24 Python
HTML5本地存储之Web Storage详解
2016/07/04 HTML / CSS
解决HTML5中滚动到底部的事件问题
2019/08/22 HTML / CSS
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
2019年c语言经典面试题目
2016/08/17 面试题
党风廉政承诺书
2014/03/27 职场文书
先进事迹演讲稿
2014/09/01 职场文书
学校远程教育工作总结
2015/08/11 职场文书
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python
海贼王十大潜力果实,路飞仅排第十,第一可毁世界(震震果实)
2022/03/18 日漫