Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rxjs - is there something like an wait until first Operator?

Tags:

I have two observables one$ and two$;

I want one$ only to fire when two$ has been fired at least once. This I think is essentially the skipUntil operator.

one$.skipUntil(two$).subscribe()

But let's say one$ has fired while two$ hasn't. I want a behaviour where the stream remembers that one$ has fired and will fire at least once, as soon as two$ did.

Cheers

like image 869
Han Che Avatar asked Apr 27 '17 08:04

Han Che


People also ask

Which operator allows you to wait for a defined delay until an item is emitted?

The Delay operator modifies its source Observable by pausing for a particular increment of time (that you specify) before emitting each of the source Observable's items.

Does forkJoin wait for all observables?

forkJoin will wait for all passed observables to emit and complete and then it will emit an array or an object with last values from corresponding observables.

What is the difference between combineLatest and forkJoin?

In conclusion, both forkJoin and combineLatest produce similar results but forkJoin emits the response only after all the Observables completes. Whereas combineLatest keeps emitting responses as soon as anyone Observable starts completing.

Are observables lazy?

Promise: It is eager — It starts executing immediately once it is defined, It doesn't matter whether we are calling the then() / catch() method. Observable: It is lazy — It won't start executing until we subscribe to it.


1 Answers

This looks like you can use the zip() operator that emits the nth item only when all its source Observables have emitted nth item:

const one$ = Observable.from(['a1', 'a2', 'a3'], Scheduler.async);
const two$ = Observable.from(['b1'], Scheduler.async);

Observable.zip(one$, two$, (v1, v2) => v1)
  .subscribe(val => console.log(val));

I'm adding Scheduler.async only to simulate asynchronous behavior (for more info see combineLatest behaviour in Rxjs 5?)

This will print to console:

a1

This is ok only if you know the one$ will emit only once.

Eventually you can use combineLatest() that needs all its source Observables to emit at least one item and then emits on any emission where you can ignore two$ with a selector function.

const one$ = Observable.from(['a1', 'a2', 'a3'], Scheduler.async);
const two$ = Observable.from(['b1', 'b2'], Scheduler.async);

Observable.combineLatest(one$, two$.take(1), (v1, v2) => v1)
  .subscribe(val => console.log(val));

We know that we only want the first item from two$, the rest can be ignored.
This will print to console:

a1
a2
a3
like image 50
martin Avatar answered Sep 25 '22 11:09

martin