RxJs: lossy form of zip operator

后端 未结 5 1701
一整个雨季
一整个雨季 2021-01-02 14:40

Consider using the zip operator to zip together two infinite Observables, one of which emits items twice as frequently as the other.
The current implementation is loss-l

5条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-02 15:13

    I think the following should take always the last value from each source Observable.

    const source1 = Observable.interval(1000).publish();
    const source2 = Observable.interval(300).publish();
    
    source1.connect();
    source2.connect();
    
    Observable.defer(() => Observable.forkJoin(
            source1.takeUntil(source2.skipUntil(source1)),
            source2.takeUntil(source1.skipUntil(source2))
        ))
        .take(1)
        .repeat()
        .subscribe(console.log);
    

    Live demo: http://jsbin.com/vawewew/11/edit?js,console

    This prints:

    [ 0, 2 ]
    [ 1, 5 ]
    [ 2, 8 ]
    [ 3, 12 ]
    [ 4, 15 ]
    [ 5, 18 ]
    

    You might need to turn source1 and source2 into hot Observables if they aren't already.

    Edit:

    The core part is source1.takeUntil(source2.skipUntil(source1)). This takes values from source1 until source2 emits. But at the same time it will ignore source1 until source2 emits at least one value :).

    The forkJoin() Observable works waits until both sources complete while remembering last emission from each one of them.

    Then we want to repeat the process and so we use take(1) to complete the chain and .repeat() to resubscribe immediately.

提交回复
热议问题