Reactivo编程练习

时间:2019-07-15 03:43:41

标签: rxjs reactive-programming

我有一个可观察的源,当您单击时会发出。我想制作一个像下一张大理石图一样发出的运算符...

也就是说,它在第一次单击时发出。然后,当您有2件物品时它会发射,然后当您有3件物品时它会发射,等等。

Marble diagram

我知道可以使用扫描和过滤运算符来完成,但是我的问题是,是否可以使用bufferWhen运算符?

我尝试执行此操作(例如this),但结果却不是我期望的(第一次点击不会立即发出)。

2 个答案:

答案 0 :(得分:0)

它按照以下代码工作。尝试避免重复使用bufferWhen中的源,可能存在争用情况

const source$ = fromEvent(document, 'click').pipe(
  map(_ => new Date())
);

interval(1000).pipe(
  tap(d => console.log('CLICK:', d)),
  bufferWhen(() => {
    return source$
  })
).subscribe(console.log);

答案 1 :(得分:0)

我找到了使用groupBy运算符的解决方案。

Stackblitz中的演示。

代码如下:

function emitSequentially<T>(source$: Observable<T>) {
    return defer(() => {
        let emitWhen = 1;
        return source$.pipe(
            groupBy(_ => emitWhen),
            mergeMap(group$ =>
                group$.pipe(
                    take(emitWhen),
                    toArray(),
                    tap(_ => ++emitWhen)
                )
            )
        );
    });
}

const source1$ = fromEvent(document, 'click').pipe(
    scan<Event, number>(acc => ++acc, 0)
);
const source2$ = interval(500).pipe(
    scan(acc => ++acc, 0)
);

emitSequentially(source1$).subscribe(x => console.log('Emitting from click: ', x));
setTimeout(() => {
    emitSequentially(source2$).subscribe(x => console.log('Emitting from interval: ', x));
}, 1000);