1 |
|
2 | import { Observable } from 'rxjs';
|
3 | import { finalize } from 'rxjs/operators';
|
4 |
|
5 | /**
|
6 | * Returns an Observable that mirrors the source Observable, but will call a specified function when
|
7 | * the source terminates on complete, error or unsubscribe.
|
8 | *
|
9 | * <span class="informal">Ensure a given function will be called when a stream ends, no matter why it ended.</span>
|
10 | *
|
11 | * `finally` method accepts as a single parameter a function. This function does not accept any parameters and
|
12 | * should not return anything. It will be called whenever source Observable completes, errors or is unsubscribed,
|
13 | * which makes it good candidate to perform any necessary clean up or side effects when Observable terminates,
|
14 | * no matter how or why it terminated.
|
15 | *
|
16 | * Observable returned by `finally` will simply mirror source Observable - each time it is subscribed, source
|
17 | * Observable will be subscribed underneath.
|
18 | *
|
19 | * Note that behavior of `finally` will be repeated per every subscription, so if resulting Observable has
|
20 | * many subscribers, function passed to `finally` might be potentially called multiple times.
|
21 | *
|
22 | * Remember also that `finally` differs quite a lot from passing complete or error handler to {@link subscribe}. It will
|
23 | * return an Observable which can be further chained, while `subscribe` returns Subscription, basically ending Observable
|
24 | * chain. Function passed to `finally` will be called also when consumer of resulting Observable unsubscribes from it,
|
25 | * while handlers passed to `subscribe` will not (even complete handler). But most importantly, `finally` does not start
|
26 | * an execution of source Observable, like `subscribe` does, allowing you to set up all necessary hooks before
|
27 | * passing Observable further, even without specific knowledge how or when it will be used.
|
28 | *
|
29 | *
|
30 | * @example <caption>Call finally after complete notification</caption>
|
31 | * Rx.Observable.of(1, 2, 3)
|
32 | * .finally(() => console.log('I was finalized!'))
|
33 | * .map(x => x * 2) // `finally` returns an Observable, so we still can chain operators.
|
34 | * .subscribe(
|
35 | * val => console.log(val),
|
36 | * err => {},
|
37 | * () => console.log('I completed!')
|
38 | * );
|
39 | *
|
40 | * // Logs:
|
41 | * // 1
|
42 | * // 2
|
43 | * // 3
|
44 | * // "I completed!"
|
45 | * // "I was finalized!"
|
46 | *
|
47 | *
|
48 | *
|
49 | * @example <caption>Call finally after consumer unsubscribes</caption>
|
50 | * const o = Rx.Observable.interval(1000)
|
51 | * .finally(() => console.log('Timer stopped'));
|
52 | *
|
53 | * const subscription = o.subscribe(
|
54 | * val => console.log(val),
|
55 | * err => {},
|
56 | * () => console.log('Complete!') // Will not be called, since complete handler
|
57 | * ); // does not react to unsubscription, just to
|
58 | * // complete notification sent by the Observable itself.
|
59 | *
|
60 | * setTimeout(() => subscription.unsubscribe(), 2500);
|
61 | *
|
62 | * // Logs:
|
63 | * // 0 after 1s
|
64 | * // 1 after 2s
|
65 | * // "Timer stopped" after 2.5s
|
66 | *
|
67 | * @see {@link using}
|
68 | *
|
69 | * @param {function} callback Function to be called when source terminates (completes, errors or is unsubscribed).
|
70 | * @return {Observable} An Observable that mirrors the source, but will call the specified function on termination.
|
71 | * @method finally
|
72 | * @name finally
|
73 | * @owner Observable
|
74 | */
|
75 | export function _finally<T>(this: Observable<T>, callback: () => void): Observable<T> {
|
76 | return finalize(callback)(this) as Observable<T>;
|
77 | }
|