diff --git a/src/operator/finally.ts b/src/operator/finally.ts index a640f4f490..8f7cd42097 100644 --- a/src/operator/finally.ts +++ b/src/operator/finally.ts @@ -4,10 +4,72 @@ import { finalize } from '../operators/finalize'; /** * Returns an Observable that mirrors the source Observable, but will call a specified function when - * the source terminates on complete or error. - * @param {function} callback Function to be called when source terminates. + * the source terminates on complete, error or unsubscribe. + * + * Ensure a given function will be called when a stream ends, no matter why it ended. + * + * `finally` method accepts as a single parameter a function. This function does not accept any parameters and + * should not return anything. It will be called whenever source Observable completes, errors or is unsubscribed, + * which makes it good candidate to perform any necessary clean up or side effects when Observable terminates, + * no matter how or why it terminated. + * + * Observable returned by `finally` will simply mirror source Observable - each time it is subscribed, source + * Observable will be subscribed underneath. + * + * Note that behavior of `finally` will be repeated per every subscription, so if resulting Observable has + * many subscribers, function passed to `finally` might be potentially called multiple times. + * + * Remember also that `finally` differs quite a lot from passing complete or error handler to {@link subscribe}. It will + * return an Observable which can be further chained, while `subscribe` returns Subscription, basically ending Observable + * chain. Function passed to `finally` will be called also when consumer of resulting Observable unsubscribes from it, + * while handlers passed to `subscribe` will not (even complete handler). But most importantly, `finally` does not start + * an execution of source Observable, like `subscribe` does, allowing you to set up all necessary hooks before + * passing Observable further, even without specific knowledge how or when it will be used. + * + * + * @example Call finally after complete notification + * Rx.Observable.of(1, 2, 3) + * .finally(() => console.log('I was finalized!')) + * .map(x => x * 2) // `finally` returns an Observable, so we still can chain operators. + * .subscribe( + * val => console.log(val), + * err => {}, + * () => console.log('I completed!') + * ); + * + * // Logs: + * // 1 + * // 2 + * // 3 + * // "I completed!" + * // "I was finalized!" + * + * + * + * @example Call finally after consumer unsubscribes + * const o = Rx.Observable.interval(1000) + * .finally(() => console.log('Timer stopped')); + * + * const subscription = o.subscribe( + * val => console.log(val), + * err => {}, + * () => console.log('Complete!') // Will not be called, since complete handler + * ); // does not react to unsubscription, just to + * // complete notification sent by the Observable itself. + * + * setTimeout(() => subscription.unsubscribe(), 2500); + * + * // Logs: + * // 0 after 1s + * // 1 after 2s + * // "Timer stopped" after 2.5s + * + * @see {@link using} + * + * @param {function} callback Function to be called when source terminates (completes, errors or is unsubscribed). * @return {Observable} An Observable that mirrors the source, but will call the specified function on termination. * @method finally + * @name finally * @owner Observable */ export function _finally(this: Observable, callback: () => void): Observable {