You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NgRx Effect仅触发一次,多无人机SSE连接事件分发异常求助

解决Angular Effect中处理多个SSE连接的问题

你这情况正好踩中了concatMap和switchMap的典型局限性:前者会顺序等待前一个流完成才处理下一个,但你的SSE连接是长期存活的(不会主动完成),导致后面的action全被堵在了队列里;后者会直接取消之前的订阅,只保留最新的请求,所以只能看到最后一个drone的输出。

你需要的是mergeMap(和flatMap是同一个操作符的别名),它会为每个输入的action创建完全独立的订阅,所有流并行处理、互不干扰,完美匹配你“逐个订阅并独立处理每个事件”的需求。

修改你的Effect代码,把concatMap换成mergeMap即可:

@Effect() startStatusUpdate$ = this.actions$.pipe(
  ofType<featureActions.OpenUsedDroneUpdateStatusChannelRequest>(featureActions.ActionTypes.OpenUsedDroneUpdateStatusChannelRequest),
  // 替换concatMap为mergeMap
  mergeMap((action) => this.droneDataService.openUsedDroneUpdateStatusChannel(action.payload).pipe(
    map(result => { 
      console.log('there', action.payload.droneId);
      // 记得返回对应的Action,否则Effect无法触发状态更新
      return new featureActions.OpenUsedDroneUpdateStatusChannelSuccess(result);
    }),
    catchError((error: HttpErrorResponse) => { 
      // 错误处理要返回Action或EMPTY,避免Effect因错误中断
      return of(new featureActions.OpenUsedDroneUpdateStatusChannelFailure(error));
    }),
  )
)
);

额外提醒:

  1. mergeMap的核心特性:它不会等待前一个Observable完成,只要新action进来就立刻创建新订阅,所有订阅并行运行。对于SSE这种长期存活的流来说,刚好能实现每架无人机的连接独立存在、各自接收推送消息。
  2. 错误处理的细节:原代码里catchError返回空值会导致Effect遇到第一个错误就停止工作,一定要返回一个错误Action或者EMPTY来维持Effect的活跃性。
  3. 内存泄漏防范:如果需要在特定时机(比如组件销毁、用户退出)关闭这些SSE连接,可以在openUsedDroneUpdateStatusChannel返回的流后添加takeUntil操作符,监听销毁信号来取消订阅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:48:54