parent
							
								
									2a6e6c02ed
								
							
						
					
					
						commit
						96cbcd6da4
					
				| @ -286,7 +286,20 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr | ||||
|       return promise; | ||||
|     } | ||||
| 
 | ||||
|     static all<R>(values: any): Promise<R> { | ||||
|     static all<R>(values: any): Promise<R> { return ZoneAwarePromise.allWithCallback(values); } | ||||
| 
 | ||||
|     static allSettled<R>(values: any): Promise<R> { | ||||
|       const P = this && this.prototype instanceof ZoneAwarePromise ? this : ZoneAwarePromise; | ||||
|       return P.allWithCallback(values, { | ||||
|         thenCallback: (value: any) => ({status: 'fulfilled', value}), | ||||
|         errorCallback: (err: any) => ({status: 'rejected', reason: err}) | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     static allWithCallback<R>(values: any, callback?: { | ||||
|       thenCallback: (value: any) => any, | ||||
|       errorCallback: (err: any) => any | ||||
|     }): Promise<R> { | ||||
|       let resolve: (v: any) => void; | ||||
|       let reject: (v: any) => void; | ||||
|       let promise = new this<R>((res, rej) => { | ||||
| @ -305,13 +318,29 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr | ||||
|         } | ||||
| 
 | ||||
|         const curValueIndex = valueIndex; | ||||
|         value.then((value: any) => { | ||||
|           resolvedValues[curValueIndex] = value; | ||||
|           unresolvedCount--; | ||||
|           if (unresolvedCount === 0) { | ||||
|             resolve !(resolvedValues); | ||||
|           } | ||||
|         }, reject !); | ||||
|         try { | ||||
|           value.then( | ||||
|               (value: any) => { | ||||
|                 resolvedValues[curValueIndex] = callback ? callback.thenCallback(value) : value; | ||||
|                 unresolvedCount--; | ||||
|                 if (unresolvedCount === 0) { | ||||
|                   resolve !(resolvedValues); | ||||
|                 } | ||||
|               }, | ||||
|               (err: any) => { | ||||
|                 if (!callback) { | ||||
|                   reject !(err); | ||||
|                 } else { | ||||
|                   resolvedValues[curValueIndex] = callback.errorCallback(err); | ||||
|                   unresolvedCount--; | ||||
|                   if (unresolvedCount === 0) { | ||||
|                     resolve !(resolvedValues); | ||||
|                   } | ||||
|                 } | ||||
|               }); | ||||
|         } catch (thenErr) { | ||||
|           reject !(thenErr); | ||||
|         } | ||||
| 
 | ||||
|         unresolvedCount++; | ||||
|         valueIndex++; | ||||
|  | ||||
| @ -518,4 +518,98 @@ describe( | ||||
|           testPromiseSubClass(done); | ||||
|         } : function() { testPromiseSubClass(); }); | ||||
|       }); | ||||
| 
 | ||||
|       describe('Promise.allSettled', () => { | ||||
|         const yes = function makeFulfilledResult(value: any) { | ||||
|           return {status: 'fulfilled', value: value}; | ||||
|         }; | ||||
|         const no = function makeRejectedResult(reason: any) { | ||||
|           return {status: 'rejected', reason: reason}; | ||||
|         }; | ||||
|         const a = {}; | ||||
|         const b = {}; | ||||
|         const c = {}; | ||||
|         const allSettled = (Promise as any).allSettled; | ||||
|         it('no promise values', (done: DoneFn) => { | ||||
|           allSettled([a, b, c]).then((results: any[]) => { | ||||
|             expect(results).toEqual([yes(a), yes(b), yes(c)]); | ||||
|             done(); | ||||
|           }); | ||||
|         }); | ||||
|         it('all fulfilled', (done: DoneFn) => { | ||||
|           allSettled([ | ||||
|             Promise.resolve(a), Promise.resolve(b), Promise.resolve(c) | ||||
|           ]).then((results: any[]) => { | ||||
|             expect(results).toEqual([yes(a), yes(b), yes(c)]); | ||||
|             done(); | ||||
|           }); | ||||
|         }); | ||||
|         it('all rejected', (done: DoneFn) => { | ||||
|           allSettled([ | ||||
|             Promise.reject(a), Promise.reject(b), Promise.reject(c) | ||||
|           ]).then((results: any[]) => { | ||||
|             expect(results).toEqual([no(a), no(b), no(c)]); | ||||
|             done(); | ||||
|           }); | ||||
|         }); | ||||
|         it('mixed', (done: DoneFn) => { | ||||
|           allSettled([a, Promise.resolve(b), Promise.reject(c)]).then((results: any[]) => { | ||||
|             expect(results).toEqual([yes(a), yes(b), no(c)]); | ||||
|             done(); | ||||
|           }); | ||||
|         }); | ||||
|         it('mixed should in zone', (done: DoneFn) => { | ||||
|           const zone = Zone.current.fork({name: 'settled'}); | ||||
|           const bPromise = Promise.resolve(b); | ||||
|           const cPromise = Promise.reject(c); | ||||
|           zone.run(() => { | ||||
|             allSettled([a, bPromise, cPromise]).then((results: any[]) => { | ||||
|               expect(results).toEqual([yes(a), yes(b), no(c)]); | ||||
|               expect(Zone.current.name).toEqual(zone.name); | ||||
|               done(); | ||||
|             }); | ||||
|           }); | ||||
|         }); | ||||
|         it('poisoned .then', (done: DoneFn) => { | ||||
|           const promise = new Promise(function() {}); | ||||
|           promise.then = function() { throw new EvalError(); }; | ||||
|           allSettled([promise]).then( | ||||
|               () => { fail('should not reach here'); }, | ||||
|               (reason: any) => { | ||||
|                 expect(reason instanceof EvalError).toBe(true); | ||||
|                 done(); | ||||
|               }); | ||||
|         }); | ||||
|         const Subclass = (function() { | ||||
|           try { | ||||
|             // eslint-disable-next-line no-new-func
 | ||||
|             return Function( | ||||
|                 'class Subclass extends Promise { constructor(...args) { super(...args); this.thenArgs = []; } then(...args) { Subclass.thenArgs.push(args); this.thenArgs.push(args); return super.then(...args); } } Subclass.thenArgs = []; return Subclass;')(); | ||||
|           } catch (e) { /**/ | ||||
|           } | ||||
| 
 | ||||
|           return false; | ||||
|         }()); | ||||
| 
 | ||||
|         describe('inheritance', () => { | ||||
|           it('preserves correct subclass', () => { | ||||
|             const promise = allSettled.call(Subclass, [1]); | ||||
|             expect(promise instanceof Subclass).toBe(true); | ||||
|             expect(promise.constructor).toEqual(Subclass); | ||||
|           }); | ||||
| 
 | ||||
|           it('invoke the subclass', () => { | ||||
|             Subclass.thenArgs.length = 0; | ||||
| 
 | ||||
|             const original = Subclass.resolve(); | ||||
|             expect(Subclass.thenArgs.length).toBe(0); | ||||
|             expect(original.thenArgs.length).toBe(0); | ||||
| 
 | ||||
|             allSettled.call(Subclass, [original]); | ||||
| 
 | ||||
|             expect(original.thenArgs.length).toBe(1); | ||||
|             expect(Subclass.thenArgs.length).toBe(1); | ||||
|           }); | ||||
|         }); | ||||
|       }); | ||||
|     })); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user