好的,为了问我的问题,这里有一点背景:
我有一个 react-native 项目,它使用react-native-ble-plx库来访问设备的蓝牙。该库有一个startDeviceScan
接受回调的方法,因此我想使用rxjs
它来扫描设备一段时间,然后将它们全部收集到一个数组中,并将结果作为承诺返回。我通过组合bufferTime
和take
管道运算符来做到这一点,尽管我也设法做到了takeUntil(timer())
。这是扫描代码(注意:我也在使用打字稿):
async lookForNearbyDevices(timeout = 5000): Promise<Device[]> {
if (timeout < 1) {
throw new Error('Erro: lookForNearbyDevices requer um timeout')
}
return new Promise<Device[]>((resolve, reject) => {
const scanReader = new Observable<Device>(obs => {
this.manager.startDeviceScan(
[ServiceUUIDs],
{ allowDuplicates: false },
(err, dvc) => {
if (err) {
obs.error(err)
return
} else if (!dvc) {
// Unreachable code
return
}
if (!protocolNameMatches(dvc.name)) {
// not what I'm looking for
return
}
obs.next(dvc)
},
)
}).pipe(
distinct(dvc => dvc.id),
bufferTime(timeout),
take(1),
)
let dvcs: Device[] = []
scanReader.subscribe({
next: result => (dvcs = result),
error: err => {
console.debug(err)
reject(err)
},
complete: () => {
this.manager.stopDeviceScan()
resolve(dvcs)
},
})
})
}
问题是,当在我的设备(Android 8.0)上执行它时,bufferTime
(甚至timer
)太早发出〜2900ms,无论timeout
. 这是一个问题,因为我不想过早完成扫描;现在我可以通过在超时时间中添加 3 秒来“处理”这个问题,但我宁愿找出根本问题,也不愿依赖这种类型的拼凑。
为了弄清楚这一点,我决定尝试一个极简主义的例子:
const obs = timer(6000)
console.time('timerRXJS')
obs.subscribe({
complete() {
console.timeEnd('timerRXJS')
},
})
...而且这个例子也过早地完成了大约 2900 毫秒。
bufferTime
( 和)有什么理由timer
会像那样提前发射吗?请注意,我没有对 rxjs 调度程序等进行任何更改,因为我并不真正了解它们是如何工作的。也许有什么要弄清楚的?
任何帮助将不胜感激。