如何使可观察的缓冲区数据直到事件发生并停止缓冲?

时间:2020-05-06 14:43:03

标签: rxjs

我有来自用户的外部图纸流,我需要等到用户个人资料的数据到来。

因此,通常来说,我希望缓冲数据直到事件发生,然后播放该数据并跳过缓冲。

我可以使用外部数组来完成它,如以下代码所示(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的方式实现呢?

1 个答案:

答案 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()我们可以分别获取这些值。

StackBlitz