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

如何同步调用NgRx Component Store的Effect?等待指定Effect完成后执行另一个

实现NgRx Component Store中Effect的顺序执行

要实现startAndUpdateProgress执行完成后再调用postFileToServer,核心是监听startAndUpdateProgress依赖的numbersObservable的完成事件,再触发后续上传操作。以下是两种可行方案:

方案一:通过完成信号追踪串联操作

这种方案适合需要单独触发进度更新逻辑,或需要在多个地方复用进度完成信号的场景:

  1. 在Component Store中添加私有Subject标记进度完成:
private progressCompleted$ = new Subject<void>();
  1. 修改startAndUpdateProgress,在numbersObservable完成时发出信号:
readonly startAndUpdateProgress = this.effect<void>(
  (trigger$) => trigger$.pipe(
    exhaustMap(() =>
      this.numbersObservable.pipe(
        tapResponse({
          next: (progress) => this.updateIrisFileListProgress(progress),
          error: (error) => console.error(error)
        }),
        finalize(() => this.progressCompleted$.next()) // 进度流完成时发送信号
      )
    )
  )
);
  1. 串联操作的两种实现方式:

方式A:新Effect处理串联逻辑

readonly startProgressThenPost = this.effect<FormData>(
  (formData$) => formData$.pipe(
    exhaustMap((formData) =>
      // 先触发进度更新,再等待完成信号
      this.startAndUpdateProgress.run(void 0).pipe(
        switchMap(() => this.progressCompleted$),
        take(1), // 只取一次完成信号
        switchMap(() => 
          this.schemaUploadSrvice.postFiles(formData).pipe(
            tapResponse({
              next: () => this.updateSchemaUploadServerResponse(),
              error: (error: HttpErrorResponse) => console.error(error)
            })
          )
        )
      )
    )
  )
);

方式B:组件内手动串联触发

// 组件内先启动进度更新
this.store.startAndUpdateProgress();
// 等待进度完成后触发上传
this.store.progressCompleted$.pipe(
  take(1)
).subscribe(() => {
  this.store.postFileToServer(yourFormData);
});

方案二:直接在单个Effect中合并两个操作

如果不需要单独触发进度更新,只需要在上传前执行一次进度流程,可直接合并两个操作到一个Effect:

readonly startProgressThenPost = this.effect<FormData>(
  (formData$) => formData$.pipe(
    exhaustMap((formData) =>
      this.numbersObservable.pipe(
        // 处理进度更新
        tap((progress) => this.updateIrisFileListProgress(progress)),
        catchError((error) => {
          console.error(error);
          return EMPTY; // 捕获错误后终止流,避免影响后续上传
        }),
        ignoreElements(), // 忽略进度值,只等待流完成
        // 进度流完成后执行上传
        switchMap(() => 
          this.schemaUploadSrvice.postFiles(formData).pipe(
            tapResponse({
              next: () => this.updateSchemaUploadServerResponse(),
              error: (error: HttpErrorResponse) => console.error(error)
            })
          )
        )
      )
    )
  )
);

注意事项

  • 确保numbersObservable是有限流(会触发complete事件),否则后续上传操作永远不会执行。如果是无限流,需添加终止条件(比如takeUntil、take(n))手动结束流。
  • 使用exhaustMap可避免重复触发,防止同一时间多个并行的进度更新或上传操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:07:49