OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / tools / side_chain_tool / web / node_modules / jquery / src / deferred.js
1 define( [
2         "./core",
3         "./var/isFunction",
4         "./var/slice",
5         "./callbacks"
6 ], function( jQuery, isFunction, slice ) {
7
8 "use strict";
9
10 function Identity( v ) {
11         return v;
12 }
13 function Thrower( ex ) {
14         throw ex;
15 }
16
17 function adoptValue( value, resolve, reject, noValue ) {
18         var method;
19
20         try {
21
22                 // Check for promise aspect first to privilege synchronous behavior
23                 if ( value && isFunction( ( method = value.promise ) ) ) {
24                         method.call( value ).done( resolve ).fail( reject );
25
26                 // Other thenables
27                 } else if ( value && isFunction( ( method = value.then ) ) ) {
28                         method.call( value, resolve, reject );
29
30                 // Other non-thenables
31                 } else {
32
33                         // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
34                         // * false: [ value ].slice( 0 ) => resolve( value )
35                         // * true: [ value ].slice( 1 ) => resolve()
36                         resolve.apply( undefined, [ value ].slice( noValue ) );
37                 }
38
39         // For Promises/A+, convert exceptions into rejections
40         // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
41         // Deferred#then to conditionally suppress rejection.
42         } catch ( value ) {
43
44                 // Support: Android 4.0 only
45                 // Strict mode functions invoked without .call/.apply get global-object context
46                 reject.apply( undefined, [ value ] );
47         }
48 }
49
50 jQuery.extend( {
51
52         Deferred: function( func ) {
53                 var tuples = [
54
55                                 // action, add listener, callbacks,
56                                 // ... .then handlers, argument index, [final state]
57                                 [ "notify", "progress", jQuery.Callbacks( "memory" ),
58                                         jQuery.Callbacks( "memory" ), 2 ],
59                                 [ "resolve", "done", jQuery.Callbacks( "once memory" ),
60                                         jQuery.Callbacks( "once memory" ), 0, "resolved" ],
61                                 [ "reject", "fail", jQuery.Callbacks( "once memory" ),
62                                         jQuery.Callbacks( "once memory" ), 1, "rejected" ]
63                         ],
64                         state = "pending",
65                         promise = {
66                                 state: function() {
67                                         return state;
68                                 },
69                                 always: function() {
70                                         deferred.done( arguments ).fail( arguments );
71                                         return this;
72                                 },
73                                 "catch": function( fn ) {
74                                         return promise.then( null, fn );
75                                 },
76
77                                 // Keep pipe for back-compat
78                                 pipe: function( /* fnDone, fnFail, fnProgress */ ) {
79                                         var fns = arguments;
80
81                                         return jQuery.Deferred( function( newDefer ) {
82                                                 jQuery.each( tuples, function( i, tuple ) {
83
84                                                         // Map tuples (progress, done, fail) to arguments (done, fail, progress)
85                                                         var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
86
87                                                         // deferred.progress(function() { bind to newDefer or newDefer.notify })
88                                                         // deferred.done(function() { bind to newDefer or newDefer.resolve })
89                                                         // deferred.fail(function() { bind to newDefer or newDefer.reject })
90                                                         deferred[ tuple[ 1 ] ]( function() {
91                                                                 var returned = fn && fn.apply( this, arguments );
92                                                                 if ( returned && isFunction( returned.promise ) ) {
93                                                                         returned.promise()
94                                                                                 .progress( newDefer.notify )
95                                                                                 .done( newDefer.resolve )
96                                                                                 .fail( newDefer.reject );
97                                                                 } else {
98                                                                         newDefer[ tuple[ 0 ] + "With" ](
99                                                                                 this,
100                                                                                 fn ? [ returned ] : arguments
101                                                                         );
102                                                                 }
103                                                         } );
104                                                 } );
105                                                 fns = null;
106                                         } ).promise();
107                                 },
108                                 then: function( onFulfilled, onRejected, onProgress ) {
109                                         var maxDepth = 0;
110                                         function resolve( depth, deferred, handler, special ) {
111                                                 return function() {
112                                                         var that = this,
113                                                                 args = arguments,
114                                                                 mightThrow = function() {
115                                                                         var returned, then;
116
117                                                                         // Support: Promises/A+ section 2.3.3.3.3
118                                                                         // https://promisesaplus.com/#point-59
119                                                                         // Ignore double-resolution attempts
120                                                                         if ( depth < maxDepth ) {
121                                                                                 return;
122                                                                         }
123
124                                                                         returned = handler.apply( that, args );
125
126                                                                         // Support: Promises/A+ section 2.3.1
127                                                                         // https://promisesaplus.com/#point-48
128                                                                         if ( returned === deferred.promise() ) {
129                                                                                 throw new TypeError( "Thenable self-resolution" );
130                                                                         }
131
132                                                                         // Support: Promises/A+ sections 2.3.3.1, 3.5
133                                                                         // https://promisesaplus.com/#point-54
134                                                                         // https://promisesaplus.com/#point-75
135                                                                         // Retrieve `then` only once
136                                                                         then = returned &&
137
138                                                                                 // Support: Promises/A+ section 2.3.4
139                                                                                 // https://promisesaplus.com/#point-64
140                                                                                 // Only check objects and functions for thenability
141                                                                                 ( typeof returned === "object" ||
142                                                                                         typeof returned === "function" ) &&
143                                                                                 returned.then;
144
145                                                                         // Handle a returned thenable
146                                                                         if ( isFunction( then ) ) {
147
148                                                                                 // Special processors (notify) just wait for resolution
149                                                                                 if ( special ) {
150                                                                                         then.call(
151                                                                                                 returned,
152                                                                                                 resolve( maxDepth, deferred, Identity, special ),
153                                                                                                 resolve( maxDepth, deferred, Thrower, special )
154                                                                                         );
155
156                                                                                 // Normal processors (resolve) also hook into progress
157                                                                                 } else {
158
159                                                                                         // ...and disregard older resolution values
160                                                                                         maxDepth++;
161
162                                                                                         then.call(
163                                                                                                 returned,
164                                                                                                 resolve( maxDepth, deferred, Identity, special ),
165                                                                                                 resolve( maxDepth, deferred, Thrower, special ),
166                                                                                                 resolve( maxDepth, deferred, Identity,
167                                                                                                         deferred.notifyWith )
168                                                                                         );
169                                                                                 }
170
171                                                                         // Handle all other returned values
172                                                                         } else {
173
174                                                                                 // Only substitute handlers pass on context
175                                                                                 // and multiple values (non-spec behavior)
176                                                                                 if ( handler !== Identity ) {
177                                                                                         that = undefined;
178                                                                                         args = [ returned ];
179                                                                                 }
180
181                                                                                 // Process the value(s)
182                                                                                 // Default process is resolve
183                                                                                 ( special || deferred.resolveWith )( that, args );
184                                                                         }
185                                                                 },
186
187                                                                 // Only normal processors (resolve) catch and reject exceptions
188                                                                 process = special ?
189                                                                         mightThrow :
190                                                                         function() {
191                                                                                 try {
192                                                                                         mightThrow();
193                                                                                 } catch ( e ) {
194
195                                                                                         if ( jQuery.Deferred.exceptionHook ) {
196                                                                                                 jQuery.Deferred.exceptionHook( e,
197                                                                                                         process.stackTrace );
198                                                                                         }
199
200                                                                                         // Support: Promises/A+ section 2.3.3.3.4.1
201                                                                                         // https://promisesaplus.com/#point-61
202                                                                                         // Ignore post-resolution exceptions
203                                                                                         if ( depth + 1 >= maxDepth ) {
204
205                                                                                                 // Only substitute handlers pass on context
206                                                                                                 // and multiple values (non-spec behavior)
207                                                                                                 if ( handler !== Thrower ) {
208                                                                                                         that = undefined;
209                                                                                                         args = [ e ];
210                                                                                                 }
211
212                                                                                                 deferred.rejectWith( that, args );
213                                                                                         }
214                                                                                 }
215                                                                         };
216
217                                                         // Support: Promises/A+ section 2.3.3.3.1
218                                                         // https://promisesaplus.com/#point-57
219                                                         // Re-resolve promises immediately to dodge false rejection from
220                                                         // subsequent errors
221                                                         if ( depth ) {
222                                                                 process();
223                                                         } else {
224
225                                                                 // Call an optional hook to record the stack, in case of exception
226                                                                 // since it's otherwise lost when execution goes async
227                                                                 if ( jQuery.Deferred.getStackHook ) {
228                                                                         process.stackTrace = jQuery.Deferred.getStackHook();
229                                                                 }
230                                                                 window.setTimeout( process );
231                                                         }
232                                                 };
233                                         }
234
235                                         return jQuery.Deferred( function( newDefer ) {
236
237                                                 // progress_handlers.add( ... )
238                                                 tuples[ 0 ][ 3 ].add(
239                                                         resolve(
240                                                                 0,
241                                                                 newDefer,
242                                                                 isFunction( onProgress ) ?
243                                                                         onProgress :
244                                                                         Identity,
245                                                                 newDefer.notifyWith
246                                                         )
247                                                 );
248
249                                                 // fulfilled_handlers.add( ... )
250                                                 tuples[ 1 ][ 3 ].add(
251                                                         resolve(
252                                                                 0,
253                                                                 newDefer,
254                                                                 isFunction( onFulfilled ) ?
255                                                                         onFulfilled :
256                                                                         Identity
257                                                         )
258                                                 );
259
260                                                 // rejected_handlers.add( ... )
261                                                 tuples[ 2 ][ 3 ].add(
262                                                         resolve(
263                                                                 0,
264                                                                 newDefer,
265                                                                 isFunction( onRejected ) ?
266                                                                         onRejected :
267                                                                         Thrower
268                                                         )
269                                                 );
270                                         } ).promise();
271                                 },
272
273                                 // Get a promise for this deferred
274                                 // If obj is provided, the promise aspect is added to the object
275                                 promise: function( obj ) {
276                                         return obj != null ? jQuery.extend( obj, promise ) : promise;
277                                 }
278                         },
279                         deferred = {};
280
281                 // Add list-specific methods
282                 jQuery.each( tuples, function( i, tuple ) {
283                         var list = tuple[ 2 ],
284                                 stateString = tuple[ 5 ];
285
286                         // promise.progress = list.add
287                         // promise.done = list.add
288                         // promise.fail = list.add
289                         promise[ tuple[ 1 ] ] = list.add;
290
291                         // Handle state
292                         if ( stateString ) {
293                                 list.add(
294                                         function() {
295
296                                                 // state = "resolved" (i.e., fulfilled)
297                                                 // state = "rejected"
298                                                 state = stateString;
299                                         },
300
301                                         // rejected_callbacks.disable
302                                         // fulfilled_callbacks.disable
303                                         tuples[ 3 - i ][ 2 ].disable,
304
305                                         // rejected_handlers.disable
306                                         // fulfilled_handlers.disable
307                                         tuples[ 3 - i ][ 3 ].disable,
308
309                                         // progress_callbacks.lock
310                                         tuples[ 0 ][ 2 ].lock,
311
312                                         // progress_handlers.lock
313                                         tuples[ 0 ][ 3 ].lock
314                                 );
315                         }
316
317                         // progress_handlers.fire
318                         // fulfilled_handlers.fire
319                         // rejected_handlers.fire
320                         list.add( tuple[ 3 ].fire );
321
322                         // deferred.notify = function() { deferred.notifyWith(...) }
323                         // deferred.resolve = function() { deferred.resolveWith(...) }
324                         // deferred.reject = function() { deferred.rejectWith(...) }
325                         deferred[ tuple[ 0 ] ] = function() {
326                                 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
327                                 return this;
328                         };
329
330                         // deferred.notifyWith = list.fireWith
331                         // deferred.resolveWith = list.fireWith
332                         // deferred.rejectWith = list.fireWith
333                         deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
334                 } );
335
336                 // Make the deferred a promise
337                 promise.promise( deferred );
338
339                 // Call given func if any
340                 if ( func ) {
341                         func.call( deferred, deferred );
342                 }
343
344                 // All done!
345                 return deferred;
346         },
347
348         // Deferred helper
349         when: function( singleValue ) {
350                 var
351
352                         // count of uncompleted subordinates
353                         remaining = arguments.length,
354
355                         // count of unprocessed arguments
356                         i = remaining,
357
358                         // subordinate fulfillment data
359                         resolveContexts = Array( i ),
360                         resolveValues = slice.call( arguments ),
361
362                         // the master Deferred
363                         master = jQuery.Deferred(),
364
365                         // subordinate callback factory
366                         updateFunc = function( i ) {
367                                 return function( value ) {
368                                         resolveContexts[ i ] = this;
369                                         resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
370                                         if ( !( --remaining ) ) {
371                                                 master.resolveWith( resolveContexts, resolveValues );
372                                         }
373                                 };
374                         };
375
376                 // Single- and empty arguments are adopted like Promise.resolve
377                 if ( remaining <= 1 ) {
378                         adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
379                                 !remaining );
380
381                         // Use .then() to unwrap secondary thenables (cf. gh-3000)
382                         if ( master.state() === "pending" ||
383                                 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
384
385                                 return master.then();
386                         }
387                 }
388
389                 // Multiple arguments are aggregated like Promise.all array elements
390                 while ( i-- ) {
391                         adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
392                 }
393
394                 return master.promise();
395         }
396 } );
397
398 return jQuery;
399 } );