diff --git a/src/operator/toPromise.ts b/src/operator/toPromise.ts index d2145c5855..5af6475d72 100644 --- a/src/operator/toPromise.ts +++ b/src/operator/toPromise.ts @@ -1,5 +1,5 @@ import { Observable } from '../Observable'; -import { root } from '../util/root'; +import { toPromise as higherOrder } from '../operators/toPromise'; /* tslint:disable:max-line-length */ export function toPromise(this: Observable): Promise; @@ -56,20 +56,5 @@ export function toPromise(this: Observable, PromiseCtor: typeof Promise): * @owner Observable */ export function toPromise(this: Observable, PromiseCtor?: typeof Promise): Promise { - if (!PromiseCtor) { - if (root.Rx && root.Rx.config && root.Rx.config.Promise) { - PromiseCtor = root.Rx.config.Promise; - } else if (root.Promise) { - PromiseCtor = root.Promise; - } - } - - if (!PromiseCtor) { - throw new Error('no Promise impl found'); - } - - return new PromiseCtor((resolve, reject) => { - let value: any; - this.subscribe((x: T) => value = x, (err: any) => reject(err), () => resolve(value)); - }); + return higherOrder(PromiseCtor)(this); } diff --git a/src/operators/index.ts b/src/operators/index.ts index 4dfd96d65f..4f7ab53876 100644 --- a/src/operators/index.ts +++ b/src/operators/index.ts @@ -72,6 +72,7 @@ export { timeout } from './timeout'; export { timeoutWith } from './timeoutWith'; export { timestamp } from './timestamp'; export { toArray } from './toArray'; +export { toPromise } from './toPromise'; export { window } from './window'; export { windowCount } from './windowCount'; export { windowTime } from './windowTime'; diff --git a/src/operators/toPromise.ts b/src/operators/toPromise.ts new file mode 100644 index 0000000000..0e3fedaff4 --- /dev/null +++ b/src/operators/toPromise.ts @@ -0,0 +1,78 @@ +import { Observable } from '../Observable'; +import { root } from '../util/root'; +import { UnaryFunction } from '../interfaces'; + +/* tslint:disable:max-line-length */ +export function toPromise(): UnaryFunction, Promise>; +export function toPromise(PromiseCtor: typeof Promise): UnaryFunction, Promise>; +/* tslint:enable:max-line-length */ + +/** + * Converts an Observable sequence to a ES2015 compliant promise. + * + * @example + * // Using normal ES2015 + * let source = Rx.Observable + * .of(42) + * .toPromise(); + * + * source.then((value) => console.log('Value: %s', value)); + * // => Value: 42 + * + * // Rejected Promise + * // Using normal ES2015 + * let source = Rx.Observable + * .throw(new Error('woops')) + * .toPromise(); + * + * source + * .then((value) => console.log('Value: %s', value)) + * .catch((err) => console.log('Error: %s', err)); + * // => Error: Error: woops + * + * // Setting via the config + * Rx.config.Promise = RSVP.Promise; + * + * let source = Rx.Observable + * .of(42) + * .toPromise(); + * + * source.then((value) => console.log('Value: %s', value)); + * // => Value: 42 + * + * // Setting via the method + * let source = Rx.Observable + * .of(42) + * .toPromise(RSVP.Promise); + * + * source.then((value) => console.log('Value: %s', value)); + * // => Value: 42 + * + * @param {PromiseConstructor} [PromiseCtor] The constructor of the promise. If not provided, + * it will look for a constructor first in Rx.config.Promise then fall back to + * the native Promise constructor if available. + * @return {Promise} An ES2015 compatible promise with the last value from + * the observable sequence. + * @method toPromise + * @owner Observable + */ +export function toPromise(PromiseCtor?: typeof Promise): UnaryFunction, Promise> { + return (source: Observable) => { + if (!PromiseCtor) { + if (root.Rx && root.Rx.config && root.Rx.config.Promise) { + PromiseCtor = root.Rx.config.Promise; + } else if (root.Promise) { + PromiseCtor = root.Promise; + } + } + + if (!PromiseCtor) { + throw new Error('no Promise impl found'); + } + + return new PromiseCtor((resolve, reject) => { + let value: any; + source.subscribe((x: T) => value = x, (err: any) => reject(err), () => resolve(value)); + }); + }; +}