Angular 使用第二个API的observable存在问题

Angular 使用第二个API的observable存在问题,angular,typescript,rxjs,observable,store,Angular,Typescript,Rxjs,Observable,Store,在这里,我对RxJs非常不好,我面临一个问题 在我的一个角度分量中,我加载如下数据: this._obs$.push(this.store1.loadTypes()); this._obs$.push(this.store2.loadLimitQuantities()); // [...] forkJoin(this._obs$).subscribe( next => console.log(next), error => console.log(error) );

在这里,我对RxJs非常不好,我面临一个问题

在我的一个角度分量中,我加载如下数据:

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;
}
loadLimitQuantilities():可观察{
//API 1
const obs=this.limitQuantityService.getLimitQuantilities().pipe(share());
obs.subscribe(数据=>{
如果(数据){
常数ifs=[];
data.forEach(元素=>{
//API 2
ifs.push(this.technicalAttribTextIFSService.getType(element.ifsType).pipe(take(1),tap((type)=>{
类型?element.type=type.valueText:element.type=null;
})));
});
forkJoin(ifs).订阅(end=>{
this.limitQuantiesSubject.next(数据);
});
}否则{
控制台错误(“数量限制收费错误”);
}
});
//AP1
返回obs;
}
不幸的是,加载数据的角度组件的
下一个
接收得太早,因为API 1已完成返回数据,而不是API 2

怎么办?返回的
应该位于API 2的
forkJoin

StackBlitz:


谢谢你的帮助。

也许你需要这样的东西

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})))
    }
}
class-MyClass{
LoadLimitQuantilities():可观察的{
//API 1
返回此.limitQuantityService.GetLimitQuantilities()管道(
map((数据)=>this.getTypeRequests(数据)),
switchMap((请求)=>forkJoin(请求))
);
}
getTypeRequests(数据){
如果(!数据){
控制台错误(“数量限制收费错误”);
返回[];
}
返回data.map(元素=>this.getType(元素));
}
getType(元素){
返回此.technicalAttribTextIFSService.getType(element.ifsType)
.pipe(映射((类型)=>({…元素,类型: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
已经有了
ifsType
type
的关联,那么你可以只做“方法2”订阅-如果你使用angular,你可以只使用
async
管道订阅
loadTypes
loadLimitedQuantilities
,谢谢你的回复,但是在任何时候,数据都不会被推入主题
this.limitQuantitiesSubject.next(data)
。另外,我在
loadLimitQuantilities()
中有生成错误,我希望将它们都放在同一个函数中。在元素类型观测值解决后,是否需要将数据推送到主题中?是的,因为加载函数(
loadObjects()
)只执行一次,结果是推入存储的主题,以便我的组件可以订阅它(
private objects subject=new behavior subject([]);public objects$=this.objects subject.asObservable();
)。感谢您的回答,这对我帮助很大,另一方面,数据必须推送到一个主题中,以便我的组件可以订阅它,因此我添加了一个方法来更改存储数据,而不是直接以另一种方法返回它。