谈谈jQuery之Deferred源码剖析(2)

jQuery.Callbacks = function(){ var list = [], self = { add: function(){/*添加元素到list*/}, remove: function(){/*从list移除指定元素*/}, fire: function(){/*遍历list并触发每次元素*/} }; return self; }

一目了然,我们每执行一次jQuery.Callbacks方法,它就会返回一个独立的自定义事件对象。在tuples每个状态中执行一次jQuery.Callbacks,也就豁然开朗了—为每个状态提供一个独立的空间来添加、删除以及触发事件。

好了,关于变量tuples,我们就算大致解读完了。

state就是deferred对象的状态值嘛,我们可以通过deferred.state方法获取(稍后会见到)。

promise就是一个拥有state、always、then、promise方法的对象,每个方法详解如下:

promise = { state: function() {//返回状态值 return state; }, always: function() {//不管成功还是失败,最终都会执行该方法 deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) {...},//重头戏,稍后会详讲 promise: function( obj ) {//扩展promise,如不久我们会看见的promise.promise( deferred ); return obj != null ? jQuery.extend( obj, promise ) : promise; } }

随后声明的一个空对象deferred。

promise.pipe=promise.then,就不累赘了,下面我们来看看jQuery.each(tuples, function(i, tuple){…})都干了什么,源码如下:

/* tuples = [ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], [ "notify", "progress", jQuery.Callbacks( "memory" ) ] ] */ jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 3 ]; // promise[ done | fail | progress ] = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = [ resolved | rejected ] state = stateString; // [ reject_list | resolve_list ].disable; progress_list.lock }, tuples[ i ^ 1 ][ 2 ].disable, 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; } );

通过jQuery.each遍历tuples数组,并对其进行相关操作,比如我们拿tuples数组中的第一个元素举例:

['resolve', 'done', jQuery.Callbacks('once memory'), 'resolved']

第一步、声明的变量list指向jQuery.Callbacks返回的对象,stateString取值为'resolved'

第二步、为promise添加'done'属性,并指向第一步中list.add(fail和progress即指向属于各自的自定义事件对象)

第三步、判断stateString值,如果为'resolved'或'rejected'状态,那么就添加三个事件函数到对应的list列表中:

--改变state状态的函数

--禁止对应状态的处理,如'resolved'后,那么必定不会触发rejected状态咯,反之亦然

--禁止pending状态,都'resolved'或者'rejected'了,那么deferred肯定不会处于pending状态咯

第四步、为对象deferred,添加触发各自状态('resolved','rejected','pending')的fire相关方法:

--resolve、resolveWith

--reject、rejectWith

--notify、notifyWith

好了,jQuery.each(tuples, function(i, tuple){…})解读就到此结束了。

总结:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwfwsy.html