【问题标题】:Angular/RxJS: forkjoin with more than 6 parametersAngular/RxJS:具有超过 6 个参数的 forkjoin
【发布时间】:2022-01-09 14:50:24
【问题描述】:

我在加载我的页面之前使用 forkjoin 来初始化数据。不幸的是,我已经达到了 forkjoin 6 个参数的限制:

export class Sample implements OnInit {

  list1?: Pair[];
  list2?: Pair[];
  list3?: Pair[];
  list4?: Pair[];
  list5?: PairExt[];
  list6?: PairExt[];
  list7?: PairExt[];

  constructor(private http: HttpService,
              private httpWithCaching: HttpWithCachingService) {
  }

  ngOnInit(): void {
    this.initLists().subscribe(([list1, list2, list3, list4, list5, list6, list7]) => {
      this.list1 = list1;
      this.list2 = list2;
      this.list3 = list3;
      this.list4 = list4;
      this.list5 = list5;
      this.list6 = list6;
      this.list7 = list7;

      this.initModule();
    });
  }

  initLists(): Observable<[Pair[], Pair[], Pair[], Pair[], PairExt[], PairExt[], PairExt[]]> {
    return forkJoin([
      this.httpWithCaching.getList1(),
      this.httpWithCaching.getList2(),
      this.httpWithCaching.getList3(),
      this.httpWithCaching.getList4(),
      this.httpWithCaching.getList5(),
      this.httpWithCaching.getList6(),
      this.httpWithCaching.getList7()
    ]);
  }

  initModule(): void {
     //some requests and initialization after the lists were fetched...
  }

因此,上面的代码将不再工作,因为 forkjoin 被限制为 6 个参数。

对于我的情况,最简单的解决方案是什么?我真正想做的就是在调用我的initModule之前获取列表...

提前致谢!

【问题讨论】:

标签: angular rxjs


【解决方案1】:

也许回退到传统方法,即承诺。使用Promise.all 进行并行API 调用(类似于forkJoin)。鉴于forkJoin 将返回一个嵌套在 API 调用上的 Observable,该 API 调用将 complete,我们可以轻松地将其替换为 Promise.all


initLists(): Promise<[Pair[], Pair[], Pair[], Pair[], PairExt[], PairExt[], PairExt[]]> {
   const promises = [this.httpWithCaching.getList1(),
      this.httpWithCaching.getList2(),
      this.httpWithCaching.getList3(),
      this.httpWithCaching.getList4(),
      this.httpWithCaching.getList5(),
      this.httpWithCaching.getList6(),
      this.httpWithCaching.getList7()];

   return Promise.all(promises);
}

【讨论】:

    【解决方案2】:

    注意:未测试

    尝试在下面对 forkJoins 进行分组

       return forkJoin([
        forkJoin([
          this.httpWithCaching.getList1(),
          this.httpWithCaching.getList2(),
          this.httpWithCaching.getList3(),
          this.httpWithCaching.getList4(),
          this.httpWithCaching.getList5(),
          this.httpWithCaching.getList6(),
        ]),
        forkJoin([
           this.httpWithCaching.getList7(),
           this.httpWithCaching.getList8(),
        ])
    
     ]).pipe(
         map( x => x.flat())
      );
    

    映射对于将数据转换回一维数组很有用

    【讨论】:

    • 这看起来不错!您能否就“平面”的替代方案提出建议?我只用 es2018。
    • 是的@TeaCup [].concat(...array)
    • 不幸的是,它对我不起作用,但让它与 arr.reduce((flat, toFlatten) => flat.concat(toFlatten), []) 一起使用
    • 看起来过于复杂。它可以更容易地完成。
    • 你可以传播数组来代替flat,类似于map( ([x1, x2]) =&gt; [...x1, ...x2])
    【解决方案3】:

    换一种方式:

      initLists(): Observable<[Pair[], Pair[], Pair[], Pair[], PairExt[], PairExt[], PairExt[]]> {
        return from([
          this.httpWithCaching.getList1(),
          this.httpWithCaching.getList2(),
          this.httpWithCaching.getList3(),
          this.httpWithCaching.getList4(),
          this.httpWithCaching.getList5(),
          this.httpWithCaching.getList6(),
          this.httpWithCaching.getList7()
        ]).pipe(combineLatestAll());
      }
    

    就是这样!

    【讨论】:

    • 如果您使用旧版本的 RxJS,请在管道中使用 combineAll()
    • 为什么是减号,奇怪?
    猜你喜欢
    • 2021-10-30
    • 2018-09-07
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2017-05-03
    • 2018-12-08
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多