You need to enable JavaScript to run this app. BLE场景下相互依赖的Observables错误处理方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

BLE场景下相互依赖的Observables错误处理方案咨询

问题根因

  • 你在switchMap中手动订阅了内部通知流,内部错误被订阅回调捕获后没有正确传递到外层流,因此无法触发外层的重试逻辑
  • switchMap中混用async函数与Observable,导致返回值类型变为Promise包裹的Subscription,打乱了RxJS的错误传递链路
  • 之前的写法中错误传播链路被切断,只有连接层的错误能到达外层重试逻辑,通知层的错误被拦截在内部

正确实现方案

把所有操作都整合到同一个响应式流中,让错误可以完整向上传播,外层的重试可以覆盖所有环节:

import { from } from 'rxjs';
import { switchMap, tap, timeout, retry } from 'rxjs/operators';

const BLE_NOTIFICATION_TIMEOUT = 3000;
const MAX_RETRY_COUNT = 5;

this.ble.connect(macAddress)
  .pipe(
    tap(() => console.log('BLE连接成功')),
    // 连接成功后设置设备模式,把Promise转成Observable适配流操作
    switchMap(() => from(
      this.ble.write(macAddress, ENV.CUSTOM_SERVICE, ENV.MODE_CHARACTERISTIC, mode)
    )),
    tap(() => console.log('设备模式设置成功')),
    // 模式设置完成后开启通知订阅
    switchMap(() => this.ble.startNotification(
      macAddress,
      ENV.CUSTOM_SERVICE,
      ENV.VALUE_CHARACTERISTIC
    ).pipe(
      tap(() => console.log('收到通知数据')),
      // 通知流超时逻辑,错误会向上传递到外层
      timeout(BLE_NOTIFICATION_TIMEOUT)
    )),
    // 所有环节的错误都会触发重试,重新执行整个连接+设置+订阅流程
    retry(MAX_RETRY_COUNT)
  )
  .subscribe(
    (data) => console.log(`incoming buffer: ${new Uint8Array(data).join(':')}`),
    (error) => console.log(`超过最大重试次数,最终错误: ${error}`)
  );

逻辑说明

  • 所有异步操作都通过RxJS操作符串联,没有手动订阅,错误可以沿着流链路完整向上传递
  • 不管是connect连接失败、write设置模式失败、还是startNotification通知流抛出错误/超时,都会触发外层的retry逻辑,重新执行整个连接流程
  • 取消了switchMap内部的手动订阅和async混用,避免了类型与错误传递的问题

如果需要区分错误类型,仅对BLE相关错误重试,可以把retry(MAX_RETRY_COUNT)替换为retryWhen逻辑,自行判断错误类型后决定是否重试。

内容的提问来源于stack exchange,提问作者stephen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 07:45:03