…n042, I just added some minor touches.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -6,90 +6,82 @@ var // Static reference to slice | ||
jQuery.extend({ | ||
|
||
Deferred: function( func ) { | ||
var doneList = jQuery.Callbacks( "once memory" ), | ||
failList = jQuery.Callbacks( "once memory" ), | ||
progressList = jQuery.Callbacks( "memory" ), | ||
var tuples = [ | ||
// action, add listener, listener list | ||
[ "resolve", "done", jQuery.Callbacks("once memory") ], | ||
[ "reject", "fail", jQuery.Callbacks("once memory") ], | ||
[ "notify", "progress", jQuery.Callbacks("memory") ] | ||
], | ||
state = "pending", | ||
lists = { | ||
resolve: doneList, | ||
reject: failList, | ||
notify: progressList | ||
}, | ||
promise = { | ||
done: doneList.add, | ||
fail: failList.add, | ||
progress: progressList.add, | ||
|
||
state: function() { | ||
return state; | ||
}, | ||
|
||
// Deprecated | ||
isResolved: doneList.fired, | ||
isRejected: failList.fired, | ||
|
||
always: function() { | ||
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); | ||
deferred.done( arguments ).fail( arguments ); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jaubourg
Author
Member
|
||
return this; | ||
}, | ||
then: function( fnDone, fnFail, fnProgress ) { | ||
then: function( /* fnDone, fnFail, fnProgress */ ) { | ||
var fns = arguments; | ||
return jQuery.Deferred(function( newDefer ) { | ||
jQuery.each( { | ||
done: [ fnDone, "resolve" ], | ||
fail: [ fnFail, "reject" ], | ||
progress: [ fnProgress, "notify" ] | ||
}, function( handler, data ) { | ||
var fn = data[ 0 ], | ||
action = data[ 1 ], | ||
returned; | ||
if ( jQuery.isFunction( fn ) ) { | ||
deferred[ handler ](function() { | ||
returned = fn.apply( this, arguments ); | ||
jQuery.each( tuples, function( i, tuple ) { | ||
var action = tuple[ 0 ], | ||
fn = fns[ i ]; | ||
// deferred[ done | fail | progress ] for forwarding actions to newDefer | ||
deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? | ||
function() { | ||
var returned = fn.apply( this, arguments ); | ||
if ( returned && jQuery.isFunction( returned.promise ) ) { | ||
returned.promise().done( newDefer.resolve ).fail( newDefer.reject ).progress( newDefer.notify ); | ||
returned.promise() | ||
.done( newDefer.resolve ) | ||
.fail( newDefer.reject ) | ||
.progress( newDefer.notify ); | ||
} else { | ||
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); | ||
} | ||
}); | ||
} else { | ||
deferred[ handler ]( newDefer[ action ] ); | ||
} | ||
} : | ||
newDefer[ action ] | ||
); | ||
}); | ||
fns = null; | ||
}).promise(); | ||
}, | ||
// Get a promise for this deferred | ||
// If obj is provided, the promise aspect is added to the object | ||
promise: function( obj ) { | ||
if ( obj == null ) { | ||
obj = promise; | ||
} else { | ||
for ( var key in promise ) { | ||
obj[ key ] = promise[ key ]; | ||
} | ||
} | ||
return obj; | ||
return typeof obj === "object" ? jQuery.extend( obj, promise ) : promise; | ||
} | ||
}, | ||
deferred, | ||
key; | ||
deferred = {}; | ||
|
||
// Keep pipe for back-compat | ||
promise.pipe = promise.then; | ||
|
||
// Construct deferred | ||
deferred = promise.promise({}); | ||
// Add list-specific methods | ||
jQuery.each( tuples, function( i, tuple ) { | ||
var list = tuple[ 2 ], stateString; | ||
|
||
for ( key in lists ) { | ||
deferred[ key ] = lists[ key ].fire; | ||
deferred[ key + "With" ] = lists[ key ].fireWith; | ||
} | ||
// promise[ done | fail | progress ] = list.add | ||
promise[ tuple[1] ] = list.add; | ||
|
||
// Handle state | ||
deferred.done( function() { | ||
state = "resolved"; | ||
}, failList.disable, progressList.lock ).fail( function() { | ||
state = "rejected"; | ||
}, doneList.disable, progressList.lock ); | ||
// Handle state | ||
if ( i < 2 ) { | ||
stateString = tuple[ 0 ].replace( /e?$/, "ed" ); | ||
This comment has been minimized.
Sorry, something went wrong.
gibson042
Member
|
||
list.add(function() { | ||
state = stateString; | ||
tuples[ i ^ 1 ][ 2 ].disable(); | ||
tuples[ 2 ][ 2 ].lock(); | ||
}); | ||
This comment has been minimized.
Sorry, something went wrong.
gibson042
Member
|
||
promise[ "isR" + stateString.substr( 1 ) ] = list.fired; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jaubourg
Author
Member
|
||
} | ||
|
||
// deferred[ resolve | reject | notify ] = list.fire | ||
deferred[ tuple[0] ] = list.fire; | ||
deferred[ tuple[0] + "With" ] = list.fireWith; | ||
}); | ||
|
||
// Make the deferred a promise | ||
promise.promise( deferred ); | ||
|
||
// Call given func if any | ||
if ( func ) { | ||
@@ -101,45 +93,50 @@ jQuery.extend({ | ||
}, | ||
|
||
// Deferred helper | ||
when: function( firstParam ) { | ||
var args = sliceDeferred.call( arguments ), | ||
i = 0, | ||
length = args.length, | ||
pValues = new Array( length ), | ||
count = length, | ||
pCount = length, | ||
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? | ||
firstParam : | ||
jQuery.Deferred(), | ||
promise = deferred.promise(); | ||
function resolveFunc( i ) { | ||
return function( value ) { | ||
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value; | ||
if ( !( --count ) ) { | ||
deferred.resolveWith( deferred, args ); | ||
} | ||
}; | ||
} | ||
function progressFunc( i ) { | ||
return function( value ) { | ||
pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value; | ||
deferred.notifyWith( promise, pValues ); | ||
when: function( subordinate /* , ..., subordinateN */ ) { | ||
var i = 0, | ||
resolveValues = sliceDeferred.call( arguments ), | ||
length = resolveValues.length, | ||
progressValues = new Array( length ), | ||
|
||
// the count of uncompleted subordinates | ||
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(), | ||
promise = deferred.promise(), | ||
|
||
// Update function for both resolve and progress values | ||
updateFunc = function( i, arr ) { | ||
return function( value ) { | ||
arr[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value; | ||
if( arr === progressValues ) { | ||
deferred.notifyWith( promise, arr ); | ||
} else if ( !( --remaining ) ) { | ||
deferred.resolveWith( promise, arr ); | ||
} | ||
}; | ||
}; | ||
} | ||
|
||
// add listeners to Deferred subordinates; treat others as resolved | ||
if ( length > 1 ) { | ||
for ( ; i < length; i++ ) { | ||
if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { | ||
args[ i ].promise().done( resolveFunc(i) ).fail( deferred.reject ).progress( progressFunc(i) ); | ||
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { | ||
resolveValues[ i ].promise() | ||
.done( updateFunc( i, resolveValues ) ) | ||
.fail( deferred.reject ) | ||
.progress( updateFunc( i, progressValues ) ); | ||
} else { | ||
--count; | ||
--remaining; | ||
} | ||
} | ||
if ( !count ) { | ||
deferred.resolveWith( deferred, args ); | ||
} | ||
} else if ( deferred !== firstParam ) { | ||
deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); | ||
} | ||
|
||
// if we're not waiting on anything, resolve the master | ||
if ( !remaining ) { | ||
deferred.resolveWith( deferred, resolveValues ); | ||
} | ||
|
||
return promise; | ||
} | ||
}); | ||
I LOVE this change.