From 6a21e0f1e75bcf0b37032b7b4dc858a497458e92 Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Mon, 4 Jul 2016 16:19:28 +0300 Subject: [PATCH] docs(operators): write comprehensive JSDoc for expand() --- spec/operators/expand-spec.ts | 14 +++++++++++ src/operator/expand.ts | 47 ++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/spec/operators/expand-spec.ts b/spec/operators/expand-spec.ts index c550bc1a19..f7b6630948 100644 --- a/spec/operators/expand-spec.ts +++ b/spec/operators/expand-spec.ts @@ -7,6 +7,20 @@ const Observable = Rx.Observable; /** @test {expand} */ describe('Observable.prototype.expand', () => { + asDiagram('expand(x => x === 8 ? empty : \u2014\u20142*x\u2014| )') + ('should recursively map-and-flatten each item to an Observable', () => { + const e1 = hot('--x----| ', {x: 1}); + const e1subs = '^ !'; + const e2 = cold('--c| ', {c: 2}); + const expected = '--a-b-c-d|'; + const values = {a: 1, b: 2, c: 4, d: 8}; + + const result = e1.expand(x => x === 8 ? Observable.empty() : e2.mapTo(2 * x)); + + expectObservable(result).toBe(expected, values); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); + it('should map and recursively flatten', () => { const values = { a: 1, diff --git a/src/operator/expand.ts b/src/operator/expand.ts index 31884123f0..38bd284dc3 100644 --- a/src/operator/expand.ts +++ b/src/operator/expand.ts @@ -10,12 +10,47 @@ import {InnerSubscriber} from '../InnerSubscriber'; import {subscribeToResult} from '../util/subscribeToResult'; /** - * Returns an Observable where for each item in the source Observable, the supplied function is applied to each item, - * resulting in a new value to then be applied again with the function. - * @param {function} project the function for projecting the next emitted item of the Observable. - * @param {number} [concurrent] the max number of observables that can be created concurrently. defaults to infinity. - * @param {Scheduler} [scheduler] The Scheduler to use for managing the expansions. - * @return {Observable} an Observable containing the expansions of the source Observable. + * Recursively projects each source value to an Observable which is merged in + * the output Observable. + * + * It's similar to {@link mergeMap}, but applies the + * projection function to every source value as well as every output value. + * It's recursive. + * + * + * + * Returns an Observable that emits items based on applying a function that you + * supply to each item emitted by the source Observable, where that function + * returns an Observable, and then merging those resulting Observables and + * emitting the results of this merger. *Expand* will re-emit on the output + * Observable every source value. Then, each output value is given to the + * `project` function which returns an inner Observable to be merged on the + * output Observable. Those output values resulting from the projection are also + * given to the `project` function to produce new output values. This is how + * *expand* behaves recursively. + * + * @example Start emitting the powers of two on every click, at most 10 of them + * var clicks = Rx.Observable.fromEvent(document, 'click'); + * var powersOfTwo = clicks + * .mapTo(1) + * .expand(x => Rx.Observable.of(2 * x).delay(1000)) + * .take(10); + * powersOfTwo.subscribe(x => console.log(x)); + * + * @see {@link mergeMap} + * @see {@link mergeScan} + * + * @param {function(value: T, index: number) => Observable} project A function + * that, when applied to an item emitted by the source or the output Observable, + * returns an Observable. + * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of input + * Observables being subscribed to concurrently. + * @param {Scheduler} [scheduler=null] The Scheduler to use for subscribing to + * each projected inner Observable. + * @return {Observable} An Observable that emits the source values and also + * result of applying the projection function to each value emitted on the + * output Observable and and merging the results of the Observables obtained + * from this transformation. * @method expand * @owner Observable */