rxjs first operator is being repeatedly called?

2019-07-23 04:39发布

If I use, 2 gets printed to the console every 3 seconds:

Rx.Observable.interval(3000)
.mergeMap(() => Rx.Observable.of(3))
.concatMap(()=>Rx.Observable.of(2).first(x=>x == 2))
.subscribe((x)=>console.log(x))

If I use, 2 gets printed to the console only one time:

Rx.Observable.interval(3000)
.mergeMap(() => Rx.Observable.of(3))
.concatMap(()=>Rx.Observable.of(2))
.first(x=>x == 2)
.subscribe((x)=>console.log(x))

The difference is where I chained the first operator, but I don't understand the flow of the chain. I thought in both cases, it should only print 2 once since I have an observable of 2.

1条回答
家丑人穷心不美
2楼-- · 2019-07-23 05:08

You are confused with the first() operator. The definition of first() is:

Returns the first element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists. If no default value is given, then onError will be called.

Note the word observable sequence, aka stream. The difference of the two scenarios are as follow:

Scenario 1:

Your first() is applied to an observable that returns a value 2. Nothing is done to the Observable.interval() stream, which keeps on emitting an event every 3 seconds. That is why your console never stops logging.

Scenario 2:

The first() is applied to an Observable.interval() that continuously emits an event, every 3 seconds. Hence, your first() operator basically chops the sequence (or stop it) as soon as it finds the fulfilling condition, which is x===2. When the condition is met, the stream ends, it then returns the FIRST element of that sequence. Hence your console only logs one time.

查看更多
登录 后发表回答