jQuery源码02--(3043 , 3183) Deferred : 延迟对象 : 对异步的统一管理
//延迟对象 jQuery.extend({ Deferred: function( func ) { var tuples = [//resolve完成、reject未完成、notify进行中类似于fire,done、fail、progress回调函数的方法类似于add,jQuery.Callbacks()创建回调对象实现回调方法。映射数组。 // 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") ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ],//得到状态 fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];//是函数得到这个函数,不是函数返回假, // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .done( newDefer.resolve ) .fail( newDefer.reject ) .progress( newDefer.notify ); } else { newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); fns = null; }).promise(); }, //jQuery.extend( obj, promise )这个promise是根据函数闭包,向上去找的,把promise复制给obj, promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Keep pipe for back-compat promise.pipe = promise.then; // 映射数组进行映射的函数 jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ],//jQuery.Callbacks("once memory") stateString = tuple[ 3 ];//resolved // promise[ done | fail | progress ] = list.add=jQuery.Callbacks("once memory").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这个json赋值 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; // deferred[ resolveWith | rejectWith | notifyWith ]=jQuery.Callbacks("once memory").fireWith方法 deferred[ tuple[0] + "With" ] = list.fireWith;//继续给deferred这个json赋值 }); // 把promise复制给deferred,deferred比promise多了3个方法, promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( subordinate /* , ..., subordinateN */ ) { var i = 0, resolveValues = core_slice.call( arguments ), length = resolveValues.length, // 未完成函数的计数器,jQuery.isFunction( subordinate.promise ):subordinate的返回值是不是函数。 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values updateFunc = function( i, contexts, values ) { return function( value ) { contexts[ i ] = this; values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; if( values === progressValues ) { deferred.notifyWith( contexts, values ); } else if ( !( --remaining ) ) {//减到0时触发resolveWith方法, deferred.resolveWith( contexts, values ); } }; }, progressValues, progressContexts, resolveContexts; // add listeners to Deferred subordinates; treat others as resolved if ( length > 1 ) { progressValues = new Array( length ); progressContexts = new Array( length ); resolveContexts = new Array( length ); for ( ; i < length; i++ ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { resolveValues[ i ].promise()//返回值 .done( updateFunc( i, resolveContexts, resolveValues ) )//触发完成函数 .fail( deferred.reject )//触发失败函数 .progress( updateFunc( i, progressContexts, progressValues ) ); } else { --remaining; } } } //计时器为0时执行resolveWith方法, if ( !remaining ) { deferred.resolveWith( resolveContexts, resolveValues ); } return deferred.promise();//执行done方法, } });