jquery异步机制源码分析
来源:互联网 发布:淘宝客为什么要用软件 编辑:程序博客网 时间:2024/06/01 20:51
统揽Deferred全局,如下:
1. Deferred: function( func ) { var tuples = [], state = "pending", promise = { state: function() {}, always: function() {}, then: function() {}, promise: function( obj ) {} }, deferred = {}; promise.pipe = promise.then; jQuery.each( tuples, function( i, tuple ) {}); promise.promise( deferred ); if ( func ) { func.call( deferred, deferred ); } return deferred; }
- 可以看出,Deferred中有一个promise对象,Deferred最后返回deferred对象,deferred对象刚开始被定义为空对象,那么什么时候为其赋值呢?请看
jQuery.each( tuples, function( i, tuple ) {});
这一行代码中的内容,其中涉及tuples
定义:
var tuples = [ // action, add listener, listener list, final state [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ];
3.再看jQuery.each( tuples, function( i, tuple ) {});
jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ],// jQuery.Callbacks("once memory") stateString = tuple[ 3 ]; //即将jQuery.Callbacks.add赋值给promise的done | fail | progress回调,至此,promise的方法又多了3个 promise[ tuple[1] ] = list.add; //若stateString 有值,就向done_list或者failed_list中传入3个回调函数 if ( stateString ) { list.add( //第1个回调:将当前状态变为 [ resolved | rejected ],初始状态为pending,若list为done ,就将其状态置为resolved function() { state = stateString; }, //第2个回调:将对应状态中list.add添加的回调disable,若list为done ,就将fail中jQuery.Callbacks("once memory")添加的回调disable tuples[ i ^ 1 ][ 2 ].disable, //第3个回调:锁定当前Callbacks tuples[ 2 ][ 2 ].lock ); } // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; });
4.接下来是promise.promise( deferred );这段代码的作用是将 promise中的方法扩展到当前的deferred中,
promise.promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; }
因此,现在的deferred中的方法有:
always:() done:() fail:() notify:() notifyWith:( context, args ) pipe:( /* fnDone, fnFail, fnProgress */ ) progress:() promise:( obj ) resolve:() reject:() rejectWith:resolve:() resolveWith:( context, args ) state:() then:( /* fnDone, fnFail, fnProgress */ ) __proto__:Object
这就是最终返回的deferred对象包含的方法。
5.下面分析then方法
then: function() { return jQuery.Deferred(function( newDefer ) {}).promise(); }
先看then方法的骨架,其返回的是当前Deferred中的promise对象,不是deferred对象。then方法递归调用jQuery.Deferred(func ),且通过then方法进入jQuery.Deferred(func )时,func不为空,因此,执行
if ( func ) { func.call( deferred, deferred ); }
此时,deferred为从then中进入的jQuery.Deferred(func )返回的deferred对象,相当于下面的newDefer,即进入then方法内部jQuery.Deferred(func )中执行func,即下面的方法:
var fns = arguments;//then方法的参数, fnDone, fnFail, fnProgress function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];//将此处看成fnDone // 向deferred[ done | fail | progress ] 中添加对应的回调,此处的deferred是父Deferred中的对象 deferred[ tuple[1] ]( //回调函数开始 function(){} //回调函数结束 ); }); fns = null; }
下面分析向父deferred对象中添加的回调函数
function(){ // returned为fnDone|fnFail的返回值,即then的回调函数返回值 var returned = fn && fn.apply( this, arguments ); // 若returned.promise有值,就向returned.promise()返回的当前promise对象的3个回调函数中分别添加父级deferred的3个方法,相当于returned对象在执行resolve时便执行newDefer.resolve,即父级deferred的resolve方法,即用新返回的returned中的resolve方法替换父级deferred的resolve方法 if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .done( newDefer.resolve ) .fail( newDefer.reject ) .progress( newDefer.notify ); } else { //若returned不是promise对象,则父Deferred立即执行add进来的方法 newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); }
流程分析
- 调用resolve时,相当与调用resolveWidth,相当于调用fireWith
- fireWith即执行通过done回调函数或者then添加进来的方法,底层用Callbacks.add添加回调,且按照回调的添加顺序执行
- 若then中的回调方法返回deferred对象,就用此返回的对象的resolve替换父级deferred中的resolve。
阅读全文
0 0
- jquery异步机制源码分析
- 异步消息机制源码分析
- 异步消息机制源码分析
- Android异步消息机制及源码分析
- 源码分析 -- 异步消息处理机制
- Handler机制源码分析(异步一)
- Android异步消息机制及源码分析
- Android源码分析-异步消息机制
- jQuery源码分析-05异步队列 Deferred
- Android异步消息处理机制详解及源码分析
- Android异步消息处理机制详解及源码分析
- Android异步消息处理机制(二):源码分析
- Android异步消息处理机制详解及源码分析
- Looper、Message、MessageQueue、Handler异步消息处理机制源码分析
- Android异步消息处理机制详解及源码分析 Handler
- Android异步消息处理机制的源码分析
- Handler异步消息处理机制的源码分析
- 异步消息处理机制之Handler源码分析篇
- 计算机通信交换技术
- 使用put方法接收客户端提交的put请求
- Redis 事务
- TCP/IP
- mysql事务隔离级别 脏读,不可重复读,幻象读
- jquery异步机制源码分析
- 1013. Image Segmentation (35)解题报告
- block块中引用成员变量引起内存泄漏问题
- 【51Nod1227】平均最小公倍数-杜教筛
- Mac 安装docker
- docker安装ubuntu14.04 免登录dockerfile版
- redis基础入门-redis系列教程
- Python中的join()函数的用法
- 3个著名加密算法(MD5、RSA、DES)的解析