我有一个可观察的源,当您单击时会发出。我想制作一个像下一张大理石图一样发出的运算符...
也就是说,它在第一次单击时发出。然后,当您有2件物品时它会发射,然后当您有3件物品时它会发射,等等。
我知道可以使用扫描和过滤运算符来完成,但是我的问题是,是否可以使用bufferWhen运算符?
我尝试执行此操作(例如this),但结果却不是我期望的(第一次点击不会立即发出)。
答案 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);