@@ -4,26 +4,14 @@ define( [
44 "./callbacks"
55] , function ( jQuery , slice ) {
66
7- function Identity ( v ) {
8- return v ;
9- }
10- function Thrower ( ex ) {
11- throw ex ;
12- }
13-
14- jQuery . extend ( {
7+ jQuery . extend ( {
158
169 Deferred : function ( func ) {
1710 var tuples = [
18-
19- // action, add listener, callbacks,
20- // ... .then handlers, argument index, [final state]
21- [ "notify" , "progress" , jQuery . Callbacks ( "memory" ) ,
22- jQuery . Callbacks ( "memory" ) , 2 ] ,
23- [ "resolve" , "done" , jQuery . Callbacks ( "once memory" ) ,
24- jQuery . Callbacks ( "once memory" ) , 0 , "resolved" ] ,
25- [ "reject" , "fail" , jQuery . Callbacks ( "once memory" ) ,
26- jQuery . Callbacks ( "once memory" ) , 1 , "rejected" ]
11+ // action, add listener, listener list, final state
12+ [ "resolve" , "done" , jQuery . Callbacks ( "once memory" ) , "resolved" ] ,
13+ [ "reject" , "fail" , jQuery . Callbacks ( "once memory" ) , "rejected" ] ,
14+ [ "notify" , "progress" , jQuery . Callbacks ( "memory" ) ]
2715 ] ,
2816 state = "pending" ,
2917 promise = {
@@ -34,21 +22,13 @@ jQuery.extend( {
3422 deferred . done ( arguments ) . fail ( arguments ) ;
3523 return this ;
3624 } ,
37-
38- // Keep pipe for back-compat
39- pipe : function ( /* fnDone, fnFail, fnProgress */ ) {
25+ then : function ( /* fnDone, fnFail, fnProgress */ ) {
4026 var fns = arguments ;
41-
42- return jQuery . Deferred ( function ( newDefer ) {
27+ return jQuery . Deferred ( function ( newDefer ) {
4328 jQuery . each ( tuples , function ( i , tuple ) {
44-
45- // Map tuples (progress, done, fail) to arguments (done, fail, progress)
46- var fn = jQuery . isFunction ( fns [ tuple [ 4 ] ] ) && fns [ tuple [ 4 ] ] ;
47-
48- // deferred.progress(function() { bind to newDefer or newDefer.notify })
49- // deferred.done(function() { bind to newDefer or newDefer.resolve })
50- // deferred.fail(function() { bind to newDefer or newDefer.reject })
51- deferred [ tuple [ 1 ] ] ( function ( ) {
29+ var fn = jQuery . isFunction ( fns [ i ] ) && fns [ i ] ;
30+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
31+ deferred [ tuple [ 1 ] ] ( function ( ) {
5232 var returned = fn && fn . apply ( this , arguments ) ;
5333 if ( returned && jQuery . isFunction ( returned . promise ) ) {
5434 returned . promise ( )
@@ -66,162 +46,6 @@ jQuery.extend( {
6646 fns = null ;
6747 } ) . promise ( ) ;
6848 } ,
69- then : function ( onFulfilled , onRejected , onProgress ) {
70- var maxDepth = 0 ;
71- function resolve ( depth , deferred , handler , special ) {
72- return function ( ) {
73- var that = this === promise ? undefined : this ,
74- args = arguments ,
75- mightThrow = function ( ) {
76- var returned , then ;
77-
78- // Support: Promises/A+ section 2.3.3.3.3
79- // https://promisesaplus.com/#point-59
80- // Ignore double-resolution attempts
81- if ( depth < maxDepth ) {
82- return ;
83- }
84-
85- returned = handler . apply ( that , args ) ;
86-
87- // Support: Promises/A+ section 2.3.1
88- // https://promisesaplus.com/#point-48
89- if ( returned === deferred . promise ( ) ) {
90- throw new TypeError ( "Thenable self-resolution" ) ;
91- }
92-
93- // Support: Promises/A+ sections 2.3.3.1, 3.5
94- // https://promisesaplus.com/#point-54
95- // https://promisesaplus.com/#point-75
96- // Retrieve `then` only once
97- then = returned &&
98-
99- // Support: Promises/A+ section 2.3.4
100- // https://promisesaplus.com/#point-64
101- // Only check objects and functions for thenability
102- ( typeof returned === "object" ||
103- typeof returned === "function" ) &&
104- returned . then ;
105-
106- // Handle a returned thenable
107- if ( jQuery . isFunction ( then ) ) {
108-
109- // Special processors (notify) just wait for resolution
110- if ( special ) {
111- then . call (
112- returned ,
113- resolve ( maxDepth , deferred , Identity , special ) ,
114- resolve ( maxDepth , deferred , Thrower , special )
115- ) ;
116-
117- // Normal processors (resolve) also hook into progress
118- } else {
119-
120- // ...and disregard older resolution values
121- maxDepth ++ ;
122-
123- then . call (
124- returned ,
125- resolve ( maxDepth , deferred , Identity , special ) ,
126- resolve ( maxDepth , deferred , Thrower , special ) ,
127- resolve ( maxDepth , deferred , Identity ,
128- deferred . notify )
129- ) ;
130- }
131-
132- // Handle all other returned values
133- } else {
134-
135- // Only substitue handlers pass on context
136- // and multiple values (non-spec behavior)
137- if ( handler !== Identity ) {
138- that = undefined ;
139- args = [ returned ] ;
140- }
141-
142- // Process the value(s)
143- // Default process is resolve
144- ( special || deferred . resolveWith ) (
145- that || deferred . promise ( ) , args ) ;
146- }
147- } ,
148-
149- // Only normal processors (resolve) catch and reject exceptions
150- process = special ?
151- mightThrow :
152- function ( ) {
153- try {
154- mightThrow ( ) ;
155- } catch ( e ) {
156-
157- // Support: Promises/A+ section 2.3.3.3.4.1
158- // https://promisesaplus.com/#point-61
159- // Ignore post-resolution exceptions
160- if ( depth + 1 >= maxDepth ) {
161-
162- // Only substitue handlers pass on context
163- // and multiple values (non-spec behavior)
164- if ( handler !== Thrower ) {
165- that = undefined ;
166- args = [ e ] ;
167- }
168-
169- deferred . rejectWith ( that || deferred . promise ( ) ,
170- args ) ;
171- }
172- }
173- } ;
174-
175- // Support: Promises/A+ section 2.3.3.3.1
176- // https://promisesaplus.com/#point-57
177- // Re-resolve promises immediately to dodge false rejection from
178- // subsequent errors
179- if ( depth ) {
180- process ( ) ;
181- } else {
182- window . setTimeout ( process ) ;
183- }
184- } ;
185- }
186-
187- return jQuery . Deferred ( function ( newDefer ) {
188-
189- // progress_handlers.add( ... )
190- tuples [ 0 ] [ 3 ] . add (
191- resolve (
192- 0 ,
193- newDefer ,
194- jQuery . isFunction ( onProgress ) ?
195- onProgress :
196- Identity ,
197- newDefer . notifyWith
198- )
199- ) ;
200-
201- // fulfilled_handlers.add( ... )
202- tuples [ 1 ] [ 3 ] . add (
203- resolve (
204- 0 ,
205- newDefer ,
206- jQuery . isFunction ( onFulfilled ) ?
207- onFulfilled :
208- Identity
209- )
210- ) ;
211-
212- // rejected_handlers.add( ... )
213- tuples [ 2 ] [ 3 ] . add (
214- resolve (
215- 0 ,
216- newDefer ,
217- jQuery . isFunction ( onRejected ) ?
218- onRejected :
219- Thrower
220- )
221- ) ;
222- } ) . promise ( ) ;
223- } ,
224-
22549 // Get a promise for this deferred
22650 // If obj is provided, the promise aspect is added to the object
22751 promise : function ( obj ) {
@@ -230,54 +54,34 @@ jQuery.extend( {
23054 } ,
23155 deferred = { } ;
23256
57+ // Keep pipe for back-compat
58+ promise . pipe = promise . then ;
59+
23360 // Add list-specific methods
23461 jQuery . each ( tuples , function ( i , tuple ) {
23562 var list = tuple [ 2 ] ,
236- stateString = tuple [ 5 ] ;
63+ stateString = tuple [ 3 ] ;
23764
238- // promise.progress = list.add
239- // promise.done = list.add
240- // promise.fail = list.add
241- promise [ tuple [ 1 ] ] = list . add ;
65+ // promise[ done | fail | progress ] = list.add
66+ promise [ tuple [ 1 ] ] = list . add ;
24267
24368 // Handle state
24469 if ( stateString ) {
245- list . add (
246- function ( ) {
247-
248- // state = "resolved" (i.e., fulfilled)
249- // state = "rejected"
250- state = stateString ;
251- } ,
70+ list . add ( function ( ) {
71+ // state = [ resolved | rejected ]
72+ state = stateString ;
25273
253- // rejected_callbacks.disable
254- // fulfilled_callbacks.disable
255- tuples [ 3 - i ] [ 2 ] . disable ,
256-
257- // progress_callbacks.lock
258- tuples [ 0 ] [ 2 ] . lock
259- ) ;
74+ // [ reject_list | resolve_list ].disable; progress_list.lock
75+ } , tuples [ i ^ 1 ] [ 2 ] . disable , tuples [ 2 ] [ 2 ] . lock ) ;
26076 }
26177
262- // progress_handlers.fire
263- // fulfilled_handlers.fire
264- // rejected_handlers.fire
265- list . add ( tuple [ 3 ] . fire ) ;
266-
267- // deferred.notify = function() { deferred.notifyWith(...) }
268- // deferred.resolve = function() { deferred.resolveWith(...) }
269- // deferred.reject = function() { deferred.rejectWith(...) }
270- deferred [ tuple [ 0 ] ] = function ( ) {
271- deferred [ tuple [ 0 ] + "With" ] ( this === deferred ? promise : this , arguments ) ;
78+ // deferred[ resolve | reject | notify ]
79+ deferred [ tuple [ 0 ] ] = function ( ) {
80+ deferred [ tuple [ 0 ] + "With" ] ( this === deferred ? promise : this , arguments ) ;
27281 return this ;
27382 } ;
274-
275- // deferred.notifyWith = list.fireWith
276- // deferred.resolveWith = list.fireWith
277- // deferred.rejectWith = list.fireWith
278- deferred [ tuple [ 0 ] + "With" ] = list . fireWith ;
279- } ) ;
280-
83+ deferred [ tuple [ 0 ] + "With" ] = list . fireWith ;
84+ } ) ;
28185 // Make the deferred a promise
28286 promise . promise ( deferred ) ;
28387
@@ -292,8 +96,7 @@ jQuery.extend( {
29296
29397 // Deferred helper
29498 when : function ( subordinate /* , ..., subordinateN */ ) {
295- var method ,
296- i = 0 ,
99+ var i = 0 ,
297100 resolveValues = slice . call ( arguments ) ,
298101 length = resolveValues . length ,
299102
@@ -303,20 +106,21 @@ jQuery.extend( {
303106
304107 // the master Deferred.
305108 // If resolveValues consist of only a single Deferred, just use that.
306- master = remaining === 1 ? subordinate : jQuery . Deferred ( ) ,
109+ deferred = remaining === 1 ? subordinate : jQuery . Deferred ( ) ,
307110
308111 // Update function for both resolve and progress values
309112 updateFunc = function ( i , contexts , values ) {
310113 return function ( value ) {
311114 contexts [ i ] = this ;
312115 values [ i ] = arguments . length > 1 ? slice . call ( arguments ) : value ;
313116 if ( values === progressValues ) {
314- master . notifyWith ( contexts , values ) ;
117+ deferred . notifyWith ( contexts , values ) ;
315118 } else if ( ! ( -- remaining ) ) {
316- master . resolveWith ( contexts , values ) ;
119+ deferred . resolveWith ( contexts , values ) ;
317120 }
318121 } ;
319122 } ,
123+
320124 progressValues , progressContexts , resolveContexts ;
321125
322126 // Add listeners to Deferred subordinates; treat others as resolved
@@ -325,22 +129,11 @@ jQuery.extend( {
325129 progressContexts = new Array ( length ) ;
326130 resolveContexts = new Array ( length ) ;
327131 for ( ; i < length ; i ++ ) {
328- if ( resolveValues [ i ] &&
329- jQuery . isFunction ( ( method = resolveValues [ i ] . promise ) ) ) {
330-
331- method . call ( resolveValues [ i ] )
132+ if ( resolveValues [ i ] && jQuery . isFunction ( resolveValues [ i ] . promise ) ) {
133+ resolveValues [ i ] . promise ( )
332134 . progress ( updateFunc ( i , progressContexts , progressValues ) )
333135 . done ( updateFunc ( i , resolveContexts , resolveValues ) )
334- . fail ( master . reject ) ;
335- } else if ( resolveValues [ i ] &&
336- jQuery . isFunction ( ( method = resolveValues [ i ] . then ) ) ) {
337-
338- method . call (
339- resolveValues [ i ] ,
340- updateFunc ( i , resolveContexts , resolveValues ) ,
341- master . reject ,
342- updateFunc ( i , progressContexts , progressValues )
343- ) ;
136+ . fail ( deferred . reject ) ;
344137 } else {
345138 -- remaining ;
346139 }
@@ -349,10 +142,10 @@ jQuery.extend( {
349142
350143 // If we're not waiting on anything, resolve the master
351144 if ( ! remaining ) {
352- master . resolveWith ( resolveContexts , resolveValues ) ;
145+ deferred . resolveWith ( resolveContexts , resolveValues ) ;
353146 }
354147
355- return master . promise ( ) ;
148+ return deferred . promise ( ) ;
356149 }
357150} ) ;
358151
0 commit comments