diff --git a/modules/angular2/src/facade/async.dart b/modules/angular2/src/facade/async.dart index 38fd1babe6..ae3421f07d 100644 --- a/modules/angular2/src/facade/async.dart +++ b/modules/angular2/src/facade/async.dart @@ -9,9 +9,12 @@ class PromiseWrapper { static Future reject(obj, stackTrace) => new Future.error(obj, stackTrace != null ? stackTrace : obj is Error ? obj.stackTrace : null); - static Future all(List promises) => Future.wait(promises); + static Future all(List promises) { + return Future + .wait(promises.map((p) => p is Future ? p : new Future.value(p))); + } - static Future then(Future promise, success(value), Function onError) { + static Future then(Future promise, success(value), [Function onError]) { if (success == null) return promise.catchError(onError); return promise.then(success, onError: onError); } diff --git a/modules/angular2/src/facade/async.ts b/modules/angular2/src/facade/async.ts index a81ccfa4fd..17fca33d76 100644 --- a/modules/angular2/src/facade/async.ts +++ b/modules/angular2/src/facade/async.ts @@ -18,13 +18,13 @@ export class PromiseWrapper { return promise.catch(onError); } - static all(promises: List>): Promise { + static all(promises: List): Promise { if (promises.length == 0) return Promise.resolve([]); return Promise.all(promises); } static then(promise: Promise, success: (value: any) => T | Thenable, - rejection: (error: any, stack?: any) => T | Thenable): Promise { + rejection?: (error: any, stack?: any) => T | Thenable): Promise { return promise.then(success, rejection); } diff --git a/modules/angular2/test/facade/async_spec.ts b/modules/angular2/test/facade/async_spec.ts index 15aec817b4..253384619e 100644 --- a/modules/angular2/test/facade/async_spec.ts +++ b/modules/angular2/test/facade/async_spec.ts @@ -14,6 +14,7 @@ import { } from 'angular2/test_lib'; import {ObservableWrapper, EventEmitter, PromiseWrapper} from 'angular2/src/facade/async'; +import {ListWrapper} from 'angular2/src/facade/collection'; export function main() { describe('EventEmitter', () => { @@ -62,4 +63,45 @@ export function main() { // should call dispose on the subscription on throw // should call dispose on the subscription on return }); -} \ No newline at end of file + + // See ECMAScript 6 Spec 25.4.4.1 + describe("PromiseWrapper", () => { + describe("#all", () => { + it("should combine lists of Promises", inject([AsyncTestCompleter], (async) => { + var one = PromiseWrapper.completer(); + var two = PromiseWrapper.completer(); + + var all = PromiseWrapper.all([one.promise, two.promise]); + var allCalled = false; + + PromiseWrapper.then(one.promise, (_) => { + expect(allCalled).toBe(false); + two.resolve('two'); + }); + + PromiseWrapper.then(all, (_) => { + allCalled = true; + async.done(); + }); + + one.resolve('one'); + })); + + ListWrapper.forEach([null, true, false, 10, 'thing', {}, []], (abruptCompletion) => { + it(`should treat "${abruptCompletion}" as an "abrupt completion"`, + inject([AsyncTestCompleter], (async) => { + var one = PromiseWrapper.completer(); + + var all = PromiseWrapper.all([one.promise, abruptCompletion]); + + PromiseWrapper.then(all, (val) => { + expect(val[1]).toEqual(abruptCompletion); + async.done(); + }); + + one.resolve('one'); + })); + }); + }); + }); +}