我正在使用消耗react-native-ble-manager的React Native应用程序中的事件发射器。
handleUpdateValueForCharacteristic(data) {
console.log('Received data from ' + data.peripheral + ' characteristic ' + data.characteristic, data.value);
}
bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
我正在处理的蓝牙事件流的频率为每秒50、100或200个事件(Hz)。
我在所有事件中都以50 Hz的频率被打扰,其中一半发生在100 Hz的情况,四分之一发生在200 Hz。 用RxJS订阅此事件流的正确方法是什么?应该使用哪个运算符采样数据?
我可能是错的,但是我似乎找不到用于从事件发射器创建可观察对象的辅助方法。
答案 0 :(得分:0)
fromEventPattern
应该是您想要的。
它使您可以基于自定义事件发射(如您使用此BLE管理器所获得的)创建可观察对象。
我在下面提供了一个摘要,概述了如何使用它。
注意scan()
和filter()
的组合。通过使用前一个运算符来跟踪第n个 事件,它可以有效地更改事件的采样率,从而可以由任何订户处理。
在您的情况下,您希望scan()
还要跟踪事件的发出,因此您可以在map()
通话之后最终filter()
进行订阅,以便订阅者可以接收到它。关键是要在累积事件时跟踪scan()
内的事件状态(即滴答和事件数据属性,分别为代码段中的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>