【问题标题】:How to emit every n-th value?如何发出每个第 n 个值?
【发布时间】:2017-08-11 18:29:30
【问题描述】:

我正在使用 mousemove 事件来创建一个 observable。

Observable.fromEvent(document, 'mousemove')

我需要每 10 个事件发出一次。我该怎么办?

【问题讨论】:

    标签: javascript rxjs reactive-programming rxjs5


    【解决方案1】:

    我能想到四种不同的方法:

    bufferCount()

    Observable.range(1, 55)
      .bufferCount(10)
      .map(arr => arr[arr.length - 1])
      .subscribe(val => console.log(val));
    

    windowCount()

    Observable.range(1, 55)
      .windowCount(10)
      .switchMap(window => window.takeLast(1))
      .subscribe(val => console.log(val));
    

    去抖动()

    let source = Observable.range(1, 55).publish();
    
    source
      .debounce(val => debounceNotifier)
      .subscribe(val => console.log(val));
    
    let debounceNotifier = source
      .bufferCount(10)
      .publish();
    debounceNotifier.connect();
    
    source.connect();
    

    scan()

    Observable.range(1, 55)
      .scan((acc, val) => {
        if (acc.length === 10) {
          acc = [];
        }
        acc.push(val);
        return acc;
      }, [])
      .filter(acc => acc.length === 10)
      .map(acc => acc[acc.length - 1])
      .subscribe(val => console.log(val));
    

    但是,当使用scan() 时,它将丢弃最后一个值55

    查看所有演示:https://jsbin.com/yagayot/14/edit?js,console

    【讨论】:

    • 我正在准备 Plunkr,但这个答案说明了一切! :)
    • @martin,先生,你太棒了!非常感谢!
    【解决方案2】:

    这是一种更简单且速度更快的方法,我使用 RxJS 6 进行了测试:

    range(1, 10000000)
      .pipe(
        filter(function(value, index) { 
          return index % 10 === 0; 
        }),
      );
    

    此代码的速度是另一个答案中 bufferCountwindowCount 方法的两倍:https://jsperf.com/observable-nth/1

    这可能是因为filter 运算符使用了一个简单的计数器,而不必保留最后一个n 元素的缓冲区。我认为当n 更大或元素本身更大时,这会更快。使用 RxJS 6,您还可以轻松地将其变成您自己的自定义运算符:

    const takeEveryNth = (n: number) => filter((value, index) => index % n === 0);
    // usage: rxjs.range(1, 10000000).pipe(takeEveryNth(10));
    

    这也是官方文档中解释如何创建自定义运算符的代码:https://github.com/ReactiveX/rxjs/blob/6.2.2/doc/pipeable-operators.md

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-30
      • 2018-11-15
      • 2022-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多