@@ -202,154 +202,166 @@ function qFactory(nextTick, exceptionHandler) {
202
202
return [ wrap ( resolveFn ) , wrap ( rejectFn ) ] ;
203
203
}
204
204
205
- /**
206
- * @ngdoc
207
- * @name ng.$q#defer
208
- * @methodOf ng.$q
209
- * @description
210
- * Creates a `Deferred` object which represents a task which will finish in the future.
211
- *
212
- * @returns {Deferred } Returns a new instance of deferred.
213
- */
214
- var defer = function ( ) {
215
- var pending = [ ] ,
216
- value ,
217
- status = 0 ,
218
- deferred ,
219
- processScheduled = false ;
220
-
221
- function processQueue ( ) {
222
- var fn , promise ;
223
-
224
- processScheduled = false ;
225
- if ( ! status ) return ;
226
- for ( var i = 0 ; i < pending . length ; ++ i ) {
227
- promise = pending [ i ] [ 0 ] ;
228
- fn = pending [ i ] [ status ] ;
229
- try {
230
- if ( isFunction ( fn ) ) {
231
- promise . resolve ( fn ( value ) ) ;
232
- } else if ( status === 1 ) {
233
- promise . resolve ( value ) ;
234
- } else {
235
- promise . reject ( value ) ;
236
- }
237
- } catch ( e ) {
238
- promise . reject ( e ) ;
239
- exceptionHandler ( e ) ;
240
- }
241
- }
242
- pending = [ ] ;
205
+ function makePromise ( value , resolved ) {
206
+ var result = defer ( ) ;
207
+ if ( resolved ) {
208
+ result . resolve ( value ) ;
209
+ } else {
210
+ result . reject ( value ) ;
243
211
}
212
+ return result . promise ;
213
+ }
244
214
245
- function scheduleProcessQueue ( ) {
246
- if ( processScheduled ) return ;
247
- processScheduled = true ;
248
- nextTick ( processQueue ) ;
215
+ function handleCallback ( value , isResolved , callback ) {
216
+ var callbackOutput = null ;
217
+ try {
218
+ if ( isFunction ( callback ) ) callbackOutput = callback ( ) ;
219
+ } catch ( e ) {
220
+ return makePromise ( e , false ) ;
249
221
}
222
+ if ( callbackOutput && isFunction ( callbackOutput . then ) ) {
223
+ return callbackOutput . then ( function ( ) {
224
+ return makePromise ( value , isResolved ) ;
225
+ } , function ( error ) {
226
+ return makePromise ( error , false ) ;
227
+ } ) ;
228
+ } else {
229
+ return makePromise ( value , isResolved ) ;
230
+ }
231
+ }
232
+
250
233
251
- function resolve ( val ) {
252
- var then , fns ;
234
+ function processQueue ( state ) {
235
+ var fn , promise ;
253
236
254
- if ( status ) return ;
255
- if ( val === deferred . promise ) throw new TypeError ( 'Cycle detected' ) ;
256
- fns = callOnce ( resolve , reject ) ;
237
+ state . processScheduled = false ;
238
+ if ( ! state . status ) return ;
239
+ for ( var i = 0 ; i < state . pending . length ; ++ i ) {
240
+ promise = state . pending [ i ] [ 0 ] ;
241
+ fn = state . pending [ i ] [ state . status ] ;
257
242
try {
258
- if ( ( isObject ( val ) || isFunction ( val ) ) ) then = val && val . then ;
259
- if ( isFunction ( then ) ) {
260
- then . call ( val , fns [ 0 ] , fns [ 1 ] , deferred . notify ) ;
243
+ if ( isFunction ( fn ) ) {
244
+ promise . resolve ( fn ( state . value ) ) ;
245
+ } else if ( state . status === 1 ) {
246
+ promise . resolve ( state . value ) ;
261
247
} else {
262
- value = val ;
263
- status = 1 ;
264
- scheduleProcessQueue ( ) ;
248
+ promise . reject ( state . value ) ;
265
249
}
266
250
} catch ( e ) {
267
- fns [ 1 ] ( e ) ;
251
+ promise . reject ( e ) ;
268
252
exceptionHandler ( e ) ;
269
253
}
270
254
}
255
+ state . pending = [ ] ;
256
+ }
257
+
258
+ function scheduleProcessQueue ( state ) {
259
+ if ( state . processScheduled ) return ;
260
+ state . processScheduled = true ;
261
+ nextTick ( function ( ) { processQueue ( state ) ; } ) ;
262
+ }
263
+
264
+ function Promise ( state ) {
265
+ this . $$state = state ;
266
+ }
267
+
268
+ Promise . prototype . then = function ( onFulfilled , onRejected , progressBack ) {
269
+ var result = defer ( ) ;
270
+
271
+ this . $$state . pending . push ( [ result , onFulfilled , onRejected , progressBack ] ) ;
272
+ if ( this . $$state . status ) scheduleProcessQueue ( this . $$state ) ;
273
+
274
+ return result . promise ;
275
+ } ;
276
+
277
+ Promise . prototype [ "catch" ] = function ( callback ) {
278
+ return this . then ( null , callback ) ;
279
+ } ;
280
+
281
+ Promise . prototype [ "finally" ] = function ( callback , progressBack ) {
282
+ return this . then ( function ( value ) {
283
+ return handleCallback ( value , true , callback ) ;
284
+ } , function ( error ) {
285
+ return handleCallback ( error , false , callback ) ;
286
+ } , progressBack ) ;
287
+ } ;
288
+
289
+
290
+ function Defer ( ) {
291
+ this . $$state = {
292
+ pending : [ ] ,
293
+ status : 0 ,
294
+ value : undefined ,
295
+ processScheduled : false
296
+ } ;
297
+ this . promise = new Promise ( this . $$state ) ;
298
+ }
299
+
300
+ Defer . prototype . resolve = function ( val ) {
301
+ var then , fns ;
271
302
272
- function reject ( reason ) {
273
- if ( status ) return ;
274
- value = reason ;
275
- status = 2 ;
276
- scheduleProcessQueue ( ) ;
303
+ if ( this . $$state . status ) return ;
304
+ if ( val === this . promise ) throw new TypeError ( 'Cycle detected' ) ;
305
+ fns = callOnce ( this . resolve , this . reject ) ;
306
+ try {
307
+ if ( ( isObject ( val ) || isFunction ( val ) ) ) then = val && val . then ;
308
+ if ( isFunction ( then ) ) {
309
+ then . call ( val , fns [ 0 ] , fns [ 1 ] , this . notify ) ;
310
+ } else {
311
+ this . $$state . value = val ;
312
+ this . $$state . status = 1 ;
313
+ scheduleProcessQueue ( this . $$state ) ;
314
+ }
315
+ } catch ( e ) {
316
+ fns [ 1 ] ( e ) ;
317
+ exceptionHandler ( e ) ;
277
318
}
319
+ } ;
278
320
279
- deferred = {
280
- promise : {
281
- then : function ( onFulfilled , onRejected , progressBack ) {
282
- var result = defer ( ) ;
283
-
284
- pending . push ( [ result , onFulfilled , onRejected , progressBack ] ) ;
285
- if ( status ) scheduleProcessQueue ( ) ;
286
-
287
- return result . promise ;
288
- } ,
289
-
290
- "catch" : function ( callback ) {
291
- return deferred . promise . then ( null , callback ) ;
292
- } ,
293
-
294
- "finally" : function ( callback , progressBack ) {
295
- function makePromise ( value , resolved ) {
296
- var result = defer ( ) ;
297
- if ( resolved ) {
298
- result . resolve ( value ) ;
299
- } else {
300
- result . reject ( value ) ;
301
- }
302
- return result . promise ;
303
- }
321
+ Defer . prototype . reject = function ( reason ) {
322
+ if ( this . $$state . status ) return ;
323
+ this . $$state . value = reason ;
324
+ this . $$state . status = 2 ;
325
+ scheduleProcessQueue ( this . $$state ) ;
326
+ } ;
304
327
305
- function handleCallback ( value , isResolved ) {
306
- var callbackOutput = null ;
307
- try {
308
- if ( isFunction ( callback ) ) callbackOutput = callback ( ) ;
309
- } catch ( e ) {
310
- return makePromise ( e , false ) ;
311
- }
312
- if ( callbackOutput && isFunction ( callbackOutput . then ) ) {
313
- return callbackOutput . then ( function ( ) {
314
- return makePromise ( value , isResolved ) ;
315
- } , function ( error ) {
316
- return makePromise ( error , false ) ;
317
- } ) ;
318
- } else {
319
- return makePromise ( value , isResolved ) ;
320
- }
321
- }
328
+ Defer . prototype . notify = function ( progress ) {
329
+ var callbacks = this . $$state . pending ;
322
330
323
- return this . then ( function ( value ) {
324
- return handleCallback ( value , true ) ;
325
- } , function ( error ) {
326
- return handleCallback ( error , false ) ;
327
- } , progressBack ) ;
328
- }
329
- } ,
330
- resolve : resolve ,
331
- reject : reject ,
332
- notify : function ( progress ) {
333
- var callbacks = pending ;
334
-
335
- if ( ! status && callbacks . length ) {
336
- nextTick ( function ( ) {
337
- var callback , result ;
338
- for ( var i = 0 , ii = callbacks . length ; i < ii ; i ++ ) {
339
- result = callbacks [ i ] [ 0 ] ;
340
- callback = callbacks [ i ] [ 3 ] ;
341
- try {
342
- result . notify ( isFunction ( callback ) ? callback ( progress ) : progress ) ;
343
- } catch ( e ) {
344
- exceptionHandler ( e ) ;
345
- }
346
- }
347
- } ) ;
331
+ if ( ! this . $$state . status && callbacks . length ) {
332
+ nextTick ( function ( ) {
333
+ var callback , result ;
334
+ for ( var i = 0 , ii = callbacks . length ; i < ii ; i ++ ) {
335
+ result = callbacks [ i ] [ 0 ] ;
336
+ callback = callbacks [ i ] [ 3 ] ;
337
+ try {
338
+ result . notify ( isFunction ( callback ) ? callback ( progress ) : progress ) ;
339
+ } catch ( e ) {
340
+ exceptionHandler ( e ) ;
341
+ }
348
342
}
349
- }
350
- } ;
343
+ } ) ;
344
+ }
345
+ } ;
346
+
347
+ /**
348
+ * @ngdoc
349
+ * @name ng.$q#defer
350
+ * @methodOf ng.$q
351
+ * @description
352
+ * Creates a `Deferred` object which represents a task which will finish in the future.
353
+ *
354
+ * @returns {Deferred } Returns a new instance of deferred.
355
+ */
356
+ var defer = function ( ) {
357
+
358
+ var result = new Defer ( ) ;
359
+ result . resolve = bind ( result , result . resolve ) ;
360
+ result . reject = bind ( result , result . reject ) ;
361
+ result . notify = bind ( result , result . notify ) ;
362
+ result . promise = new Promise ( result . $$state ) ;
351
363
352
- return deferred ;
364
+ return result ;
353
365
} ;
354
366
355
367
/**
0 commit comments