如何在无嵌套订阅下获取ConcatMap循环中Observable的实际数据?
RxJS 按顺序执行并获取嵌套请求的实际数据
你当前代码的核心问题是:第二个concatMap中用observableOf包裹了账户对应的请求Observable数组,导致最终拿到的data$是Observable集合而非实际返回的数据。以下是重构后的代码,无需嵌套订阅即可获取到instruction和brokerage的实际数据:
this.subscriptions.push( this.service1 .subscribeToHouseholdId() .pipe( // 第一步:获取账户列表和模板数据 concatMap((householdId: number) => { return forkJoin([this.service2.getAccounts(householdId), this.service3.getTemplates()]); }), // 第二步:针对每个账户执行两个请求,批量获取实际数据 concatMap(([accountResponse, templates]) => { // 为每个账户生成请求Observable,再用forkJoin批量执行 const accountDataObservables = accountResponse?.results.map((account) => { return forkJoin([ this.service3.getData1(account.id), this.service3.getData2(account.id) ]); }) || []; // 用forkJoin等待所有账户请求完成,同时携带accountResponse和templates数据 return forkJoin(accountDataObservables).pipe( map((accountDataList) => [accountDataList, accountResponse, templates]) ); }) ) .subscribe(([accountDataList, accountResponse, templatesResponse]) => { const accountResults = accountResponse as IAccount; const templates = templatesResponse as ITemplate; const templatesData = this.filterTemplatesData(templates); accountResults?.results.forEach((account, index) => { // 直接从accountDataList中获取当前账户的实际数据 const [instruction, brokerage] = accountDataList[index]; const tableData = instruction as IInstruction[]; const bepData = brokerage as IPlan; // 这里可以使用tableData和bepData做后续处理 }); }) );
关键修改说明:
- 移除
observableOf包裹:将每个账户对应的forkJoin([getData1, getData2])收集到数组中,再用外层forkJoin执行所有这些请求,确保等待所有账户的请求完成后返回实际数据数组。 - 调整
concatMap返回逻辑:通过forkJoin(accountDataObservables).pipe(map(...)),将账户的实际数据与之前的accountResponse、templates一起传递到订阅回调中。 - 订阅回调中直接使用实际数据:
accountDataList的每个元素对应一个账户的[instruction, brokerage]实际数据,无需再处理Observable对象。
内容的提问来源于stack exchange,提问作者jak dev
相关产品推荐
相关产品推荐

