1 | import { Observable } from '../Observable';
|
---|
2 | import { Operator } from '../Operator';
|
---|
3 | import { Subscriber } from '../Subscriber';
|
---|
4 | import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
|
---|
5 |
|
---|
6 | /**
|
---|
7 | * Returns an Observable that skips all items emitted by the source Observable as long as a specified condition holds
|
---|
8 | * true, but emits all further source items as soon as the condition becomes false.
|
---|
9 | *
|
---|
10 | * ![](skipWhile.png)
|
---|
11 | *
|
---|
12 | * @param {Function} predicate - A function to test each item emitted from the source Observable.
|
---|
13 | * @return {Observable<T>} An Observable that begins emitting items emitted by the source Observable when the
|
---|
14 | * specified predicate becomes false.
|
---|
15 | * @method skipWhile
|
---|
16 | * @owner Observable
|
---|
17 | */
|
---|
18 | export function skipWhile<T>(predicate: (value: T, index: number) => boolean): MonoTypeOperatorFunction<T> {
|
---|
19 | return (source: Observable<T>) => source.lift(new SkipWhileOperator(predicate));
|
---|
20 | }
|
---|
21 |
|
---|
22 | class SkipWhileOperator<T> implements Operator<T, T> {
|
---|
23 | constructor(private predicate: (value: T, index: number) => boolean) {
|
---|
24 | }
|
---|
25 |
|
---|
26 | call(subscriber: Subscriber<T>, source: any): TeardownLogic {
|
---|
27 | return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate));
|
---|
28 | }
|
---|
29 | }
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * We need this JSDoc comment for affecting ESDoc.
|
---|
33 | * @ignore
|
---|
34 | * @extends {Ignored}
|
---|
35 | */
|
---|
36 | class SkipWhileSubscriber<T> extends Subscriber<T> {
|
---|
37 | private skipping: boolean = true;
|
---|
38 | private index: number = 0;
|
---|
39 |
|
---|
40 | constructor(destination: Subscriber<T>,
|
---|
41 | private predicate: (value: T, index: number) => boolean) {
|
---|
42 | super(destination);
|
---|
43 | }
|
---|
44 |
|
---|
45 | protected _next(value: T): void {
|
---|
46 | const destination = this.destination;
|
---|
47 | if (this.skipping) {
|
---|
48 | this.tryCallPredicate(value);
|
---|
49 | }
|
---|
50 |
|
---|
51 | if (!this.skipping) {
|
---|
52 | destination.next(value);
|
---|
53 | }
|
---|
54 | }
|
---|
55 |
|
---|
56 | private tryCallPredicate(value: T): void {
|
---|
57 | try {
|
---|
58 | const result = this.predicate(value, this.index++);
|
---|
59 | this.skipping = Boolean(result);
|
---|
60 | } catch (err) {
|
---|
61 | this.destination.error(err);
|
---|
62 | }
|
---|
63 | }
|
---|
64 | }
|
---|