4 promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
5 // Static reference to slice
6 sliceDeferred = [].slice;
9 // Create a simple deferred (one callbacks list)
10 _Deferred: function() {
13 // stored [ context , args ]
15 // to avoid firing when already doing so
17 // flag to know if the deferred has been cancelled
19 // the deferred itself
35 for ( i = 0, length = args.length; i < length; i++ ) {
37 type = jQuery.type( elem );
38 if ( type === "array" ) {
39 deferred.done.apply( deferred, elem );
40 } else if ( type === "function" ) {
41 callbacks.push( elem );
45 deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
51 // resolve with given context and args
52 resolveWith: function( context, args ) {
53 if ( !cancelled && !fired && !firing ) {
54 // make sure args are available (#8421)
58 while( callbacks[ 0 ] ) {
59 callbacks.shift().apply( context, args );
63 fired = [ context, args ];
70 // resolve with this as context and given arguments
72 deferred.resolveWith( this, arguments );
76 // Has this deferred been resolved?
77 isResolved: function() {
78 return !!( firing || fired );
92 // Full fledged deferred (two callbacks list)
93 Deferred: function( func ) {
94 var deferred = jQuery._Deferred(),
95 failDeferred = jQuery._Deferred(),
97 // Add errorDeferred methods, then and promise
98 jQuery.extend( deferred, {
99 then: function( doneCallbacks, failCallbacks ) {
100 deferred.done( doneCallbacks ).fail( failCallbacks );
103 fail: failDeferred.done,
104 rejectWith: failDeferred.resolveWith,
105 reject: failDeferred.resolve,
106 isRejected: failDeferred.isResolved,
107 // Get a promise for this deferred
108 // If obj is provided, the promise aspect is added to the object
109 promise: function( obj ) {
116 var i = promiseMethods.length;
118 obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
123 // Make sure only one callback list will be used
124 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
126 delete deferred.cancel;
127 // Call given func if any
129 func.call( deferred, deferred );
135 when: function( firstParam ) {
136 var args = arguments,
138 length = args.length,
140 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
143 function resolveFunc( i ) {
144 return function( value ) {
145 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
146 if ( !( --count ) ) {
147 deferred.resolveWith( deferred, args );
152 for( ; i < length; i++ ) {
153 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
154 args[ i ].promise().then( resolveFunc(i), deferred.reject );
160 deferred.resolveWith( deferred, args );
162 } else if ( deferred !== firstParam ) {
163 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
165 return deferred.promise();