javascript中promise处理蓝牙需封装web bluetooth api为promise链:requestdevice和connect本身返回promise,可直接await;组合搜索、连接、读取需按序await,确保gatt操作在连接后执行,并注意浏览器兼容性与安全上下文要求。

JavaScript 中使用 Promise 处理蓝牙设备搜索与连接,核心是将 Web Bluetooth API 的基于事件和回调的操作(如 requestDevice、connect)封装为 Promise 风格,让异步流程更清晰、可链式调用、易错误处理。
封装 requestDevice 为 Promise
原生 navigator.bluetooth.requestDevice() 返回 Promise,但它的 resolve 值是 BluetoothDevice,而实际搜索过程(如过滤、用户选择)由浏览器 UI 控制。你只需处理成功或失败即可,无需额外封装——但它本身已是 Promise:
- 直接 await 调用,配合
filters或optionalServices提高匹配精度 - 捕获
NotFoundError(用户未选设备)、SecurityError(未在安全上下文或未用户手势触发)等常见拒绝原因
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
async function selectBluetoothDevice() {
try {
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['battery_service'] }], // 按服务名过滤
optionalServices: ['device_information']
});
return device;
} catch (err) {
console.error('设备选择失败:', err.name, err.message);
throw err;
}
}
将 device.gatt.connect() 封装为 Promise
device.gatt.connect() 本身返回 Promise,但部分浏览器旧版本可能不支持,且连接失败时的错误类型较分散(如 NetworkError、SecurityError)。建议显式包装并统一错误逻辑:
- 检查
device.gatt是否存在(避免空引用) - await
device.gatt.connect(),它会在连接建立后 resolve,失败时 reject - 连接成功后,
device.gatt.server即为可用的BluetoothRemoteGATTServer
示例:
async function connectToDevice(device) {
if (!device.gatt) {
throw new Error('设备不支持 GATT');
}
try {
const server = await device.gatt.connect();
return server;
} catch (err) {
console.error('GATT 连接失败:', err.name, err.message);
throw err;
}
}
组合搜索 + 连接 + 读取服务的完整 Promise 流程
把设备发现、连接、获取服务、读取特征值串成 Promise 链或 async/await 序列,避免嵌套回调,便于错误冒泡和统一处理:
- 每个步骤都用
await,任一环节 reject 都会进入catch - 读取电池电量示例:先
getPrimaryService,再getCharacteristic,最后readValue() - 注意:所有 GATT 操作必须在连接成功后执行,且需处理特征值编码(如
value.getUint8(0))
示例:
async function scanAndReadBattery() {
try {
const device = await selectBluetoothDevice();
const server = await connectToDevice(device);
const service = await server.getPrimaryService('battery_service');
const characteristic = await service.getCharacteristic('battery_level');
const value = await characteristic.readValue();
const level = value.getUint8(0);
console.log('电池电量:', level, '%');
return level;
} catch (err) {
console.error('蓝牙全流程失败:', err);
}
}
注意事项与兼容性提醒
Web Bluetooth 在 Chrome / Edge(桌面)支持良好,但 Safari 和 Firefox 不支持;移动端仅 Chrome for Android 支持。使用前务必检查环境:
- 确认
'bluetooth' in navigator为 true - 确保页面运行在 HTTPS 或 localhost(安全上下文)
- 所有蓝牙调用必须由用户手势(如 click)触发,不能在页面加载时自动执行
- 连接后记得在适当时候调用
device.gatt.disconnect()释放资源(可封装为 Promise)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










