Web Worker 无法直接访问蓝牙 API,需通过主线程采集数据、Worker 计算的协作模式处理传感器原始流;主线程用 postMessage 零拷贝传递 ArrayBuffer,Worker 解析、滤波、单位换算后回传结构化结果。

在 HTML5 中,Web Worker 不能直接访问蓝牙 API(如 navigator.bluetooth),因为蓝牙接口是主线程专属的、受用户手势触发且涉及安全上下文限制。但你可以通过“主线程采集 + Worker 计算”的协作模式,高效处理从蓝牙传感器读取的原始数据(如加速度计、心率、温湿度等二进制流)。关键在于:主线程负责连接、读取和分发数据,Worker 负责解析、滤波、单位换算、特征提取等 CPU 密集型任务。
主线程:建立连接并转发原始数据给 Worker
使用 BluetoothRemoteGATTCharacteristic.readValue() 或监听 characteristic.addEventListener('characteristicvaluechanged', ...) 获取 ArrayBuffer 或 Uint8Array。避免在主线程做复杂解析(如浮点解包、滑动平均),而是将原始字节直接传给 Worker:
- 用
worker.postMessage(rawData, [rawData.buffer])零拷贝传递 ArrayBuffer(注意:传递后主线程不能再读写该 buffer) - 可附带元信息,如设备 ID、特征 UUID、时间戳(
Date.now())、采样率等,用普通对象封装后一同发送 - 示例:
worker.postMessage({ type: 'sensor-data', deviceId: 'abc', uuid: '00002a37-0000-1000-8000-00805f9b34fb', data: new Uint8Array(buffer) }, [buffer])
Worker 线程:专注解析与转换逻辑
在 Worker 内定义对应传感器的数据格式解析规则(如 IEEE-754 浮点、补码整数、LE/BE 字节序)。常见操作包括:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 按协议提取字段:例如某心率服务返回
[flags, bpm, rr1, rr2, ...],用view.getUint8(0)读标志位,view.getUint8(1)读心率值 - 多字节转换:温度传感器返回 2 字节有符号小端整数,用
view.getInt16(0, true) / 100得到 ℃ 值 - 低通滤波或移动平均:维护一个固定长度的 Float32Array 缓冲区,在每次新数据到达时更新并输出平滑值
- 避免 DOM 操作和任何 Web API(如 fetch、localStorage),只做纯计算
双向通信与结果回传
Worker 处理完后,将结构化结果(如 { timestamp, x: 0.23, y: -1.17, z: 9.81, unit: 'm/s²' })发回主线程:
立即学习“前端免费学习笔记(深入)”;
- 主线程监听
worker.onmessage,收到后可更新图表、触发事件或存入 IndexedDB - 若需动态调整 Worker 行为(如切换滤波系数),主线程可发控制消息,Worker 用
onmessage接收并更新内部参数 - 注意:频繁传大量数据会增加序列化开销,优先使用 Transferable(如 ArrayBuffer);结构化对象建议精简字段
实际部署注意事项
确保整个流程符合 Web Bluetooth 规范和浏览器限制:
- 必须在安全上下文(HTTPS 或 localhost)中运行
- 蓝牙请求(
navigator.bluetooth.requestDevice)必须由用户手势(如 click)触发 - Worker 文件需同源,且不能是内联脚本(必须是独立 .js 文件)
- 对高频率传感器(如 IMU 100Hz+),建议启用通知(
characteristic.startNotifications())并批量聚合若干帧再发给 Worker,减少通信频次


















