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

RxJS:如何并行发起两个HTTP请求,确保第一个先发射结果

解决方案:并行请求+有序发射

要实现并行发起两个API请求,同时保证/games/:id的结果先发射、截图请求的结果必须等前者完成后再发射,可以利用RxJS的merge和delayUntil操作符来实现,既简洁又满足需求:

export class GameService {
  constructor(private http: HttpClient) {}

  private state: GameState = {
    ...initialState,
  };
  private store = new BehaviorSubject<GameState>(this.state);
  private store$ = this.store.asObservable();

  findGame(id: string) {
    // 游戏详情请求Observable,完成后直接更新状态
    const game$ = this.http.get<Game>(`${env.BASE_URL}/games/${id}`).pipe(
      tap((game) => {
        this.state = { ...this.state, selectedGame: game };
        this.store.next({ ...this.state });
      })
    );

    // 截图请求Observable,添加delayUntil确保必须等game$完成后才继续执行后续逻辑
    const screenshots$ = this.http
      .get<APIResponse<{ image: string }>>(
        `${env.BASE_URL}/games/${id}/screenshots`
      )
      .pipe(
        map(({ results: screenshots }) => screenshots),
        // 关键:等待game$完成后才处理截图结果
        delayUntil(game$),
        tap((screenshots) => {
          // 此时selectedGame必然存在,无需额外判断
          this.state.selectedGame.screenshots = [...screenshots];
          this.store.next({ ...this.state });
        })
      );

    // merge会同时订阅两个Observable,实现并行请求
    return merge(game$, screenshots$);
  }
}

关键逻辑说明:

  • 并行请求:merge操作符会同时订阅game$和screenshots$,两个API请求会立刻并行发起,不会像concatMap那样串行等待。
  • 有序发射:screenshots$中使用delayUntil(game$),会强制等待game$完成后才处理截图的结果并发射,完全满足「即使截图请求先完成,也要等详情请求完成后再更新状态」的需求。
  • 代码简洁性:相比复杂的merge手动控制顺序的方案,这个实现逻辑清晰,维护成本低,同时去掉了原代码中不必要的if (this.state.selectedGame)判断(因为delayUntil确保了此时详情已经存在)。

对比原方案的优势:

原方案用concatMap导致请求串行,浪费了并行请求的性能;而新方案既保留了并行请求的高效性,又严格保证了状态更新的顺序,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:25:19