代码之家  ›  专栏  ›  技术社区  ›  Olivier MATROT

反应式编程:如何订阅和采样事件发射器?

  •  0
  • Olivier MATROT  · 技术社区  · 7 年前

    我使用的是正在消费的React本机应用程序中的事件发射器 react-native-ble-manager

    handleUpdateValueForCharacteristic(data) {
    
        console.log('Received data from ' + data.peripheral + ' characteristic ' + data.characteristic, data.value);
    
      }
    bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
    

    我正在处理一个蓝牙事件流,其频率为每秒50、100或200个事件(Hz)。

    我在所有的事件中都以50赫兹的频率参与,其中一半在100赫兹,四分之一在200赫兹。 使用RxJS订阅此事件流的正确方式是什么?我应该使用哪个操作符来采样数据?

    我可能错了,但我似乎找不到一个助手方法来从事件发射器创建一个可观察的对象。

    1 回复  |  直到 7 年前
        1
  •  0
  •   miqh    7 年前

    fromEventPattern 应该是你要找的。

    它允许您基于自定义事件发射创建一个可观察的事件(就像您使用这个可观察的管理器所得到的一样)。

    我在下面提供了一个片段,概述了如何使用它。

    注意 scan() filter() 事件,它可以有效地更改事件的采样率,从而由任何订阅者处理。

    在您的场景中,您将需要 扫描() map() 它是在 过滤器() 呼叫,以便订户将收到它。这里的关键点是跟踪事件的状态 扫描() (即勾号和事件数据属性, t data 分别在代码段中)累积事件。

    const { fromEventPattern } = rxjs;
    const { filter, map, scan } = rxjs.operators;
    
    // Tweak parameters to vary demo
    const hz = 200;
    const sample = 4;
    
    function addEmitterHandler(handler) {
      // bleManagerEmitter.addListener('event', handler)
      const intervalId = setInterval(() => {
        handler({ timestamp: Date.now() });
      }, 1000 / hz);
      return intervalId;
    }
    
    function removeEmitterHandler(handler, intervalId) {
      // bleManagerEmitter.removeListener(...)
      clearInterval(intervalId);
    }
    
    // Simulate emissions using the `setInterval()` call
    const emitter = fromEventPattern(
      addEmitterHandler,
      removeEmitterHandler
    );
    
    emitter.pipe(
      // Use `scan()` and `filter()` combination to adjust sampling
      scan((state, data) => {
        const t = (state.t % (sample + 1)) + 1;
        return { t, data };
      }, { t: 0, data: null }),
      filter(state => state.t % sample === 0),
      // Use `map()` to forward event data only
      map(state => state.data),
    ).subscribe(data => console.log(data));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>