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实例教程(19) 使用HoTMetal(6)
Dec 23 Javascript
Sample script that displays all of the users in a given SQL Server DB
Jun 16 Javascript
ExtJS4 组件化编程,动态加载,面向对象,Direct
May 12 Javascript
jquery 面包屑导航 具体实现
Jun 05 Javascript
jQuery.holdReady()使用方法
May 20 Javascript
jQuery实现标题有打字效果的焦点图代码
Nov 16 Javascript
AngularJS ng-change 指令的详解及简单实例
Jul 30 Javascript
javascript深拷贝的原理与实现方法分析
Apr 10 Javascript
在vue中安装使用vux的教程详解
Sep 16 Javascript
Vue.js的复用组件开发流程完整记录
Nov 29 Javascript
vue form check 表单验证的实现代码
Dec 09 Javascript
JavaScript封装单向链表的示例代码
Sep 17 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数据库连接
2006/10/09 PHP
php5.2.0内存管理改进
2007/01/22 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
更正确的asp冒泡排序
2007/05/24 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
2013/05/08 Javascript
jquery 表格排序、实时搜索表格内容(附图)
2014/05/19 Javascript
给应用部分的js代码设定一个统一的入口
2014/06/15 Javascript
AngularJS的一些基本样式初窥
2015/07/27 Javascript
AngularJS 依赖注入详解和简单实例
2016/07/28 Javascript
jQuery查找节点方法完整实例
2016/09/13 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
Bootstrap 3 按钮标签实例代码
2017/02/21 Javascript
angular-ngSanitize模块-$sanitize服务详解
2017/06/13 Javascript
JS实现的找零张数最小问题示例
2017/11/28 Javascript
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
vue-router 实现导航守卫(路由卫士)的实例代码
2018/09/02 Javascript
js实现时间日期校验
2020/05/26 Javascript
Openlayers+EasyUI Tree动态实现图层控制
2020/09/28 Javascript
jQuery实现鼠标拖动图片功能
2021/03/04 jQuery
win7安装python生成随机数代码分享
2013/12/27 Python
Python获取远程文件大小的函数代码分享
2014/05/13 Python
简单了解python PEP的一些知识
2019/07/13 Python
Python如何在windows环境安装pip及rarfile
2020/06/15 Python
HTML5 Canvas实现烟花绽放特效
2016/03/02 HTML / CSS
作为网站管理者应当如何防范XSS
2014/08/16 面试题
教师实习自我鉴定
2013/12/11 职场文书
毕业生求职自荐信怎么写
2014/01/08 职场文书
房屋所有权证明
2014/10/20 职场文书
工作经历证明书范文
2014/11/02 职场文书
2015年幼儿园班务工作总结
2015/05/12 职场文书
餐馆开业致辞
2015/08/01 职场文书
运动会口号霸气押韵
2015/12/24 职场文书
2016年秋季趣味运动会开幕词
2016/03/04 职场文书
《最后一头战象》读后感:动物也有感情
2020/01/02 职场文书
java协程框架quasar和kotlin中的协程对比分析
2022/02/24 Java/Android