deferred = jQuery.Deferred(), 
completeDeferred = jQuery.Callbacks( "once memory" ), 
deferred.promise( jqXHR ); 
jqXHR.success = jqXHR.done; 
jqXHR.error = jqXHR.fail; 
jqXHR.complete = completeDeferred.add; 
queue那边也没变多少。
复制代码 代码如下:
 
(function( jQuery ) { 
function handleQueueMarkDefer( elem, type, src ) { 
var deferDataKey = type + "defer", 
queueDataKey = type + "queue", 
markDataKey = type + "mark", 
defer = jQuery._data( elem, deferDataKey ); 
if ( defer && 
( src =https://www.jb51.net/article/== "queue" || !jQuery._data(elem, queueDataKey) ) && 
( src =https://www.jb51.net/article/== "mark" || !jQuery._data(elem, markDataKey) ) ) { 
// Give room for hard-coded callbacks to fire first 
// and eventually mark/queue something else on the element 
setTimeout( function() { 
if ( !jQuery._data( elem, queueDataKey ) && 
!jQuery._data( elem, markDataKey ) ) { 
jQuery.removeData( elem, deferDataKey, true ); 
defer.fire(); 
} 
}, 0 ); 
} 
} 
jQuery.extend({ 
_mark: function( elem, type ) { 
if ( elem ) { 
type = ( type || "fx" ) + "mark"; 
jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); 
} 
}, 
_unmark: function( force, elem, type ) { 
if ( force !== true ) { 
type = elem; 
elem = force; 
force = false; 
} 
if ( elem ) { 
type = type || "fx"; 
var key = type + "mark", 
count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); 
if ( count ) { 
jQuery._data( elem, key, count ); 
} else { 
jQuery.removeData( elem, key, true ); 
handleQueueMarkDefer( elem, type, "mark" ); 
} 
} 
}, 
queue: function( elem, type, data ) { 
var q; 
if ( elem ) { 
type = ( type || "fx" ) + "queue"; 
q = jQuery._data( elem, type ); 
// Speed up dequeue by getting out quickly if this is just a lookup 
if ( data ) { 
if ( !q || jQuery.isArray(data) ) { 
q = jQuery._data( elem, type, jQuery.makeArray(data) ); 
} else { 
q.push( data ); 
} 
} 
return q || []; 
} 
}, 
dequeue: function( elem, type ) { 
type = type || "fx"; 
var queue = jQuery.queue( elem, type ), 
fn = queue.shift(), 
hooks = {}; 
// If the fx queue is dequeued, always remove the progress sentinel 
if ( fn =https://www.jb51.net/article/== "inprogress" ) { 
fn = queue.shift(); 
} 
if ( fn ) { 
// Add a progress sentinel to prevent the fx queue from being 
// automatically dequeued 
if ( type =https://www.jb51.net/article/== "fx" ) { 
queue.unshift( "inprogress" ); 
} 
jQuery._data( elem, type + ".run", hooks ); 
fn.call( elem, function() { 
jQuery.dequeue( elem, type ); 
}, hooks ); 
} 
if ( !queue.length ) { 
jQuery.removeData( elem, type + "queue " + type + ".run", true ); 
handleQueueMarkDefer( elem, type, "queue" ); 
} 
} 
}); 
jQuery.fn.extend({ 
queue: function( type, data ) { 
var setter = 2; 
if ( typeof type !== "string" ) { 
data = type; 
type = "fx"; 
setter--; 
} 
if ( arguments.length < setter ) { 
return jQuery.queue( this[0], type ); 
} 
return data =https://www.jb51.net/article/== undefined ? 
this : 
this.each(function() { 
var queue = jQuery.queue( this, type, data ); 
if ( type =https://www.jb51.net/article/== "fx" && queue[0] !== "inprogress" ) { 
jQuery.dequeue( this, type ); 
} 
}); 
}, 
dequeue: function( type ) { 
return this.each(function() { 
jQuery.dequeue( this, type ); 
}); 
}, 
// Based off of the plugin by Clint Helfers, with permission. 
//  
delay: function( time, type ) { 
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 
type = type || "fx"; 
return this.queue( type, function( next, hooks ) { 
var timeout = setTimeout( next, time ); 
hooks.stop = function() { 
clearTimeout( timeout ); 
}; 
}); 
}, 
clearQueue: function( type ) { 
return this.queue( type || "fx", [] ); 
}, 
// Get a promise resolved when queues of a certain type 
// are emptied (fx is the type by default) 
promise: function( type, object ) { 
if ( typeof type !== "string" ) { 
object = type; 
type = undefined; 
} 
type = type || "fx"; 
var defer = jQuery.Deferred(), 
elements = this, 
i = elements.length, 
count = 1, 
deferDataKey = type + "defer", 
queueDataKey = type + "queue", 
markDataKey = type + "mark", 
tmp; 
function resolve() { 
if ( !( --count ) ) { 
defer.resolveWith( elements, [ elements ] ); 
} 
} 
while( i-- ) { 
if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || 
( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || 
jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && 
jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { 
count++; 
tmp.add( resolve ); 
} 
} 
resolve(); 
return defer.promise( object ); 
} 
}); 
})( jQuery ); 
这时候,钩子机制其实已经在jQuery内部蔓延起来,1.5是css模块的cssHooks,1.6是属性模块的attrHooks, propHooks, boolHooks, nodeHooks,1.7是事件模块的fixHooks, keyHooks, mouseHooks,1.8是queue模块的_queueHooks,由于_queueHooks,queue终于瘦身了。
复制代码 代码如下:
