fix(ble): 设备列表 UI 刷新加 300ms 节流,修复搜到设备后点击卡死
搜索开启 allowDuplicatesKey=true,目标设备广播包每秒到达数次且 RSSI 逐包变化——upsertDevice 的签名判重只拦"完全相同"的包,挡不住信号 强度变化。每包都会走 setDeviceMap → onDeviceListChange → React setState → 页面重渲染,搜到设备后以每秒数十次的频率打满渲染线程, 点击事件被排队到数百毫秒后处理,表现为"搜到设备就无法停搜索"。 - setDeviceMap 改用 emitDeviceListThrottled:数据实时合入 deviceMap, 通知 UI 压到每 300ms 一次 - resetDeviceMap/stopSearch 绕过节流立即冲刷:清空与最终帧不能延迟 - cleanupDiscovery 补清节流定时器
This commit is contained in:
parent
2bc487c522
commit
ac4cb3b0f9
|
|
@ -15,6 +15,9 @@ const FILTER_SCAN_TIMEOUT_MS = 4000
|
||||||
const RESTART_SCAN_DELAY_MS = 120
|
const RESTART_SCAN_DELAY_MS = 120
|
||||||
const DISCOVERY_POLL_INTERVAL_MS = 1200
|
const DISCOVERY_POLL_INTERVAL_MS = 1200
|
||||||
const SCAN_DURATION_MS = 30000
|
const SCAN_DURATION_MS = 30000
|
||||||
|
// 设备列表 UI 刷新最小间隔:搜索中 allowDuplicatesKey=true,目标设备每秒广播
|
||||||
|
// 数次,不节流会以每秒数十次 setState 打满小程序渲染线程,点击被排队卡死
|
||||||
|
const DEVICE_LIST_EMIT_INTERVAL_MS = 300
|
||||||
const TARGET_NAME_KEYWORDS = Object.freeze(['ED713', '713WQ', 'ED719', 'EP832'])
|
const TARGET_NAME_KEYWORDS = Object.freeze(['ED713', '713WQ', 'ED719', 'EP832'])
|
||||||
|
|
||||||
function promisifyTaroApi(apiName, params = {}) {
|
function promisifyTaroApi(apiName, params = {}) {
|
||||||
|
|
@ -80,6 +83,7 @@ export function createBluetoothDiscovery(options = {}) {
|
||||||
let filterFallbackTimer = null
|
let filterFallbackTimer = null
|
||||||
let discoveryPollTimer = null
|
let discoveryPollTimer = null
|
||||||
let autoStopTimer = null
|
let autoStopTimer = null
|
||||||
|
let deviceListEmitTimer = null
|
||||||
|
|
||||||
let offDeviceFound = null
|
let offDeviceFound = null
|
||||||
let offAdapterState = null
|
let offAdapterState = null
|
||||||
|
|
@ -116,14 +120,41 @@ export function createBluetoothDiscovery(options = {}) {
|
||||||
onDeviceListChange(getSortedDeviceList())
|
onDeviceListChange(getSortedDeviceList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 广播包持续到达时(RSSI 每包都变,签名判重挡不住),节流 UI 刷新;
|
||||||
|
// 数据仍实时合入 deviceMap,只是通知 UI 的频率被压到每 300ms 一次。
|
||||||
|
// 末包到达后补一次尾部刷新,保证最后一帧数据不丢
|
||||||
|
function emitDeviceListThrottled() {
|
||||||
|
if (deviceListEmitTimer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceListEmitTimer = setTimeout(() => {
|
||||||
|
deviceListEmitTimer = null
|
||||||
|
emitDeviceList()
|
||||||
|
}, DEVICE_LIST_EMIT_INTERVAL_MS)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearDeviceListEmitTimer() {
|
||||||
|
if (!deviceListEmitTimer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(deviceListEmitTimer)
|
||||||
|
deviceListEmitTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
function setDeviceMap(nextMap) {
|
function setDeviceMap(nextMap) {
|
||||||
deviceMap = nextMap
|
deviceMap = nextMap
|
||||||
onDeviceMapChange({...deviceMap})
|
onDeviceMapChange({...deviceMap})
|
||||||
emitDeviceList()
|
emitDeviceListThrottled()
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetDeviceMap() {
|
function resetDeviceMap() {
|
||||||
setDeviceMap({})
|
clearDeviceListEmitTimer()
|
||||||
|
deviceMap = {}
|
||||||
|
onDeviceMapChange({...deviceMap})
|
||||||
|
// 重置列表必须立即通知:清空操作不能等 300ms 节流窗口
|
||||||
|
emitDeviceList()
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeUuid(uuid) {
|
function normalizeUuid(uuid) {
|
||||||
|
|
@ -687,6 +718,10 @@ export function createBluetoothDiscovery(options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
await stopDiscoverySilently()
|
await stopDiscoverySilently()
|
||||||
|
|
||||||
|
// 停搜后立即冲刷最后一帧列表,避免 pending 的节流定时器延迟刷新
|
||||||
|
clearDeviceListEmitTimer()
|
||||||
|
emitDeviceList()
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickPreferredDeviceId(deviceId) {
|
function pickPreferredDeviceId(deviceId) {
|
||||||
|
|
@ -874,6 +909,7 @@ export function createBluetoothDiscovery(options = {}) {
|
||||||
function cleanupDiscovery() {
|
function cleanupDiscovery() {
|
||||||
clearFallbackTimer()
|
clearFallbackTimer()
|
||||||
clearDiscoveryPollTimer()
|
clearDiscoveryPollTimer()
|
||||||
|
clearDeviceListEmitTimer()
|
||||||
|
|
||||||
searchSessionId += 1
|
searchSessionId += 1
|
||||||
acceptingDeviceEvents = false
|
acceptingDeviceEvents = false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue