使用第二个 API 的可观察对象的问题

Problem with an observable that uses a second API

好吧,我对 RxJs 真的很糟糕,我遇到了一个问题。

在我的一个 Angular 组件中,我像这样加载数据:

this._obs$.push(this.store1.loadTypes());
this._obs$.push(this.store2.loadLimitQuantities());
// [...]
    
forkJoin(this._obs$).subscribe(
  next => console.log(next),
  error => console.log(error)
);

其中一个可观察对象从 API 1 接收数据,然后需要从 API 1 接收的数据中检索来自 API 2 的数据:

loadLimitQuantities(): Observable<LimitQuantity[]> {
    // API 1
    const obs = this.limitQuantityService.getLimitQuantities().pipe(share());
    obs.subscribe(data => {
        if (data) {
            const ifs = [];
            data.forEach(element => {
                // API 2
                ifs.push(this.technicalAttribTextIFSService.getType(element.ifsType).pipe(take(1), tap((type) => { 
                    type ? element.type = type.valueText : element.type = null;
                })));
            });
            forkJoin(ifs).subscribe(end => {
                this.limitQuantitiesSubject.next(data);
            });
        } else {
            console.error("Erreur lors du chargement des quantités limites");
        }
    });
    // AP1
    return obs;
}

不幸的是,加载数据的 Angular 组件的 next 接收得太早,因为 API 1 已完成返回数据,但 API 2.

怎么办? return 应该在 API 的 forkJoin 2.

堆栈闪电战: here

感谢您的帮助。

也许您需要这样的东西?

class MyClass {

    loadLimitQuantities(): Observable < LimitQuantity[] > {
        // API 1
        return this.limitQuantityService.getLimitQuantities().pipe(
            map((data) => this.getTypeRequests(data)),
            switchMap((requests) => forkJoin(requests))
        );
    }

    getTypeRequests(data) {
      if(!data) {
          console.error("Erreur lors du chargement des quantités limites");
          return [];
      }

      return data.map(element => this.getType(element));
    }

    getType(element) {
        return this.technicalAttribTextIFSService.getType(element.ifsType)
            .pipe(map((type) => ({...element, type: type ? type.valueText : null})))
    }
}

您获得限制数量,将它们映射到类型请求,然后将它们连接在一起。

我不确定我是否 100% 解决了您的问题 - 但我认为这会满足您的需求。

limitedQuantitiesWithTypeFromApi2$ = this.loadLimitQuantities()
    .pipe(
        switchMap(
          x => forkJoin(x.map(y => this.getType(y.ifsType))), 
        ),
      );

  ngOnInit() {
    forkJoin(this.loadTypes(), this.limitedQuantitiesWithTypeFromApi2$)
      .subscribe(([types, lq]) => console.log('Original 1', types, lq));

    forkJoin(this.loadTypes(), this.loadLimitQuantities())
      .pipe(
        map(([types, lq]) => {
          return lq.map(x => ({
            ...x, 
            type: types.find(y => y.ifsType === x.ifsType)
          }))
        })
      )
      .subscribe(x => console.log('Alternate Approach', x));

  }

  loadTypes() {
    return timer(1000).pipe(
      map(x => ([
        { ifsType: 1, type: 'vText1'}, 
        { ifsType: 2, type: 'vText2'}
      ])),
      share()
    );
  }

  loadLimitQuantities() {
    return timer(1000).pipe(
      map(x => ([
        {ifsType: 1, type: null, }, 
        {ifsType: 2, type: null }
      ])),
      share(),
    );
  }

  getType(ifsType: number) {
    return timer(1000).pipe(
      map(x => ifsType === 1 ? 'vText1' : 'vText2'),
      map(x => ({ ifsType, type: x })),
      share()
    );
  }

但是,我认为可以安全地假设您的 API2 是一个 HTTP 调用 - 虽然它可以工作,但我建议您只批量获取所有“类型关联”,这样您就可以制作一个更简单的流。

我的意思是,如果 loadTypes 已经有一个 ifsTypetype 的关联,那么您可以只进行“方法 2”订阅 - 如果您使用的是 angular 无论如何,你可以只使用 async 管道订阅 loadTypesloadLimitedQuantities.