RxJs:forkJoin()无法运行,因为我的可观察对象列表不完整

时间:2019-09-11 09:16:25

标签: angular typescript rxjs observable fork-join

我有一个无法解决的问题。

我正在浏览XLSX文件中的数据列表。 对于文件的每一行,两个请求都发送到服务器:

  • 一个恢复期间
  • 的人
  • 恢复用户
  • 的另一个人

创建了一个可观察的钱包,以将其余数据存储在该行中。之后立即完成。 否则,循环将继续执行,并且列表中的最后数据将在forkjoin()中考虑在内。

因此,我使用forkJoin()等待循环中三个可观察值的结果。 一旦完成了三个可观察对象,就发送一个新请求。 就在这里阻止他。 新查询将添加到可观察对象列表中。

而且,我只想在再次通过使用forkJoin()完成可观察对象列表之后,再运行其余代码, 从XLSX文件浏览数据后。 问题是贯穿文件的循环在我的可观察对象列表包含任何内容之前结束, 并且第二个forkJoin()永远不会执行。

代码:

for(var objectives of this.XLSXObjectives) {
    if(objectives.values != 0) {
        // 2 requests (period and user)
        var period$ = this.storePeriods.getPeriod(new Period({month: objectives.values[0].month, year: objectives.values[0].year}));
        var user$ = this.storeUsers.getUser(new User({num_seller: objectives.values[0].userCode}));

        // Observable (wallet)
        var XLSXWalletSubject: BehaviorSubject<Wallet> = new BehaviorSubject<Wallet>(null);
        var XLSXWallet$: Observable<any> = XLSXWalletSubject.asObservable();
        XLSXWalletSubject.next(new Wallet({
            wallet_name: objectives.values[0].walletName,
            user: null,
            period: null,
            margin_m: 0,
            value_100: objectives.values[0].ValueAt100Percent,
            percentage_100_m: 0
        }));

        // Wait for the result of the three observables
        forkJoin(period$, user$, XLSXWallet$).subscribe(
            ([period, user, wallet]) => {
                console.warn("OK!");

                wallet.period = period;
                wallet.user = user;

                // New request
                var wallet$ = this.storeObjectives.addXLSXWallet(wallet);
                // Request is added to a list of observables
                this.observables$.push(wallet$);

                wallet$.subscribe(w => { ... });
            }
        );
        // Observable (wallet) complete
        XLSXWalletSubject.complete();
    }
}

console.warn(this.observables$); // this.observables$ = []
forkJoin(this.observables$).subscribe(results => {
    console.log("It doesn't work!!!")
});

如果有人有解决方案可以帮助我,谢谢。

1 个答案:

答案 0 :(得分:2)

我在这里不确定100%,但是我认为您需要遵循以下原则:

from(this.XLSXObjectives).pipe(
  filter(objectives => objectives.values != 0),
  mergeMap(objectives => forkJoin(
    this.storePeriods.getPeriod(new Period({month: objectives.values[0].month, year: objectives.values[0].year}),
    this.storeUsers.getUser(new User({num_seller: objectives.values[0].userCode}),
    of(new Wallet({
      wallet_name: objectives.values[0].walletName,
      user: null,
      period: null,
      margin_m: 0,
      value_100: objectives.values[0].ValueAt100Percent,
      percentage_100_m: 0
    }))
  )),
  map(([period, user, wallet]) => ({ ...wallet, period, user})),
  mergeMap(wallet => this.storeObjectives.addXLSXWallet(wallet)),
  toArray()
).subscribe(results => { // handle array of results here });
  • 目标是一一发出的
  • mergeMap订阅三个内部Observable中的forkJoin(如果您需要一次处理一个请求,请使用concatMap,并且如果您只想要某个数字并发请求,请向mergeMap添加一个并发参数
  • map调用使用walletperiod: period填充user: user对象
  • 最后一个mergeMap使用wallet对象发出下一个请求
  • toArray调用一直等到整个Observable完成并以数组形式发出所有接收到的值