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

Angular ngrx中如何让Promise.all等待前置Promise执行完成?

问题根因

这不是Promise.all的机制问题,是你写的异步时序错了:

  • 代码执行同步流时,this.getNameData().then(...)里的push逻辑会被挂到微任务队列,不会立刻执行
  • 同步流会继续往下跑,遍历names把其他Promise塞进数组后,立刻执行Promise.all(promisses),这时候那个耗时请求对应的Promise根本还没被push进数组,Promise.all自然不会等它
  • 另外你代码里还有几处拼写错误:Promisse正确拼写是Promise,fromPromisse是RxJS旧版的fromPromise(新版RxJS直接用from即可),getDataSucess正确拼写是getDataSuccess,这些也会导致运行异常。
修复方案

方案1:保持Promise写法,调整时序

所有依赖前置异步结果的逻辑,必须放到前置Promise的then回调里,等前置任务resolve之后再组装完整的Promise数组,再调用Promise.all:

effect = this.actions$.ofType(projectAction.GETDATA)
  .switchMap(([action, state]) => {
    return Observable.fromPromise(
      // 先等长任务完成拿到结果
      this.getNameData().then(serverData => {
        const promises: Promise<any>[] = [];
        // 把依赖长任务结果的请求放进数组
        promises.push(this.dataService.getAllNameData(serverData));
        // 再放入其他普通请求
        names.forEach((name) => {
          promises.push(this.dataService.getAllNameData(name));
        });
        // 此时数组是完整的,再调用Promise.all等待所有任务
        return Promise.all(promises);
      }).then((results) => {
        // 处理全量结果逻辑
        return new dataAction.getDataSuccess(results);
      })
    );
  });

方案2:RxJS原生写法(更符合NgRx最佳实践)

NgRx Effect本身基于RxJS实现,不建议混用Promise和Observable,容易出时序问题。用RxJS原生操作符实现的话逻辑更清晰,forkJoin就是Observable版的Promise.all,会等待所有传入的流完成后返回结果数组:

import { from, of } from 'rxjs';
import { switchMap, map, catchError } from 'rxjs/operators';

effect = this.actions$.ofType(projectAction.GETDATA)
  .pipe(
    switchMap(([action, state]) => {
      // 先执行前置长任务,转Promise为Observable
      return from(this.getNameData()).pipe(
        switchMap(serverData => {
          // 组装全部请求流
          const requestStreams$ = [
            this.dataService.getAllNameData(serverData),
            ...names.map(name => this.dataService.getAllNameData(name))
          ];
          // 等待所有请求完成
          return forkJoin(requestStreams$);
        }),
        map(results => new dataAction.getDataSuccess(results)),
        // 记得补充错误处理,否则请求报错后effect会终止,无法响应后续动作
        catchError(error => of(new dataAction.getDataFail(error)))
      );
    })
  );

额外提醒:如果你的dataService本身是Angular封装的HttpClient服务,它的方法默认返回Observable,不需要转成Promise用,直接把返回值放进forkJoin的数组里即可,少一层转换性能更好,也更不容易出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:03:27