我有来自用户的外部图纸流,我需要等到用户个人资料的数据到来。
因此,通常来说,我希望缓冲数据直到事件发生,然后播放该数据并跳过缓冲。
我可以使用外部数组来完成它,如以下代码所示(stackblitz):
import { of, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';
const numbers = interval(1000);
const source = numbers.pipe(
take(4)
);
let allowPerform = false;
setTimeout(_=>{allowPerform = true},2001);
const fifo=[];
source.subscribe(x => {
fifo.push(x);
if (!allowPerform) {
console.log('skip perform for:', x);
return;
}
let item ;
while ( fifo.length) {
item = fifo.shift();
console.log('perform for:', item);
}
});
其输出:
skip perform for: 0
skip perform for: 1
perform for: 0
perform for: 1
perform for: 2
perform for: 3
但是如何以RXjs的方式实现呢?
答案 0 :(得分:2)
这可能是实现此目的的方法:
// Buffer until the `notifier` emits
// Then do not buffer anymore, just send the values
const src$ = interval(1000).pipe(take(10), publish(), refCount());
const notifier$ = timer(2001);
concat(
src$.pipe(buffer(notifier$), mergeAll()),
src$
).subscribe(console.log, null, () => console.warn('complete'));
使用publish(), refCount()
将把发出的值多播到所有使用者。这是通过在源和数据使用者之间放置Subject
来实现的,这意味着不会多次订阅源。
src$.pipe(buffer(notifier$), mergeAll()),
将一直缓冲到notifier$
发出为止。但是,由于notifier$
也已完成,因此传递的整个observable将完成,从而可以订阅下一个observable(src$
)。
之所以使用mergeAll()
是因为buffer
将发出一个收集值的数组,并且使用mergeAll()
我们可以分别获取这些值。