等待rxjs中的内部观察

时间:2018-10-24 15:23:32

标签: angular rxjs

我有一个函数要在3个可观察对象完成后返回:

initialize(){
  let src1:Observable<Account>; //initialization omitted for brevity
  let src2: Observable<User>;   //initialization omitted for brevity

  // this is one is the problem
  let src3: Observable<Company[]> = this.myHttpService.getCompanies()
                                                  .pipe(
                                                     //do something that calls `this.myHttpService.getDepartments(company.id)` for each company one at a time.
                                                   );

  return merge(src1, src2, src3);                        

}

对于src3,每个公司都有多个部门。我想为每个公司打电话给this.myHttpService.getDepartments(company.id)。每个公司仅调用一次所有this.myHttpService.getDepartments。只有这样src3才是完整的。

我经历了concatMapmergeMap ....的任意组合。...我只是不明白。

我该如何接管每家公司,一次将其部门(Department[])的公司改为一家,然后完成src3的工作?

3 个答案:

答案 0 :(得分:1)

您可以使用Observable.forkJoin实现此目的。

return forkJoin([src1,src2,src3]).map(result=>{
   //output as result[0], result[1], result[2]
});

答案 1 :(得分:0)

您可能想尝试以下方法。

initialize(){
  let src1:Observable<Account>; //initialization omitted for brevity
  let src2: Observable<User>;   //initialization omitted for brevity

  // this is one is the problem
  let src3: Observable<Company[]> = this.myHttpService.getCompanies().pipe(
     map(companies: Array<any> => companies.map(
       company => this.myHttpService.getDepartments(company.id)
     )),
     switchMap(getDepObsArray: Array<Observable<any>> => forkJoin(getDepObsArray))
  );

  return forkJoin(src1, src2, src3);                        

}

想法是使用forkJoin来确保

  • src3仅在完成对服务的所有调用后才返回
  • initialize返回一个Observable,仅在src1 src2src3完成时发出

答案 2 :(得分:0)

有很多方法可以实现您的目标。您可以使用concatAll,mergeMap和toArray:

concatAll将数组解压缩为单个对象,mergeMap将这些对象转换为可观察的发光公司部门,并且toArray收集mergeMap函数的输出,以确保在可观察完成之前检索所有部门

最终代码如下:

    let src3: Observable<{company: Company, departments: Department[]}[]> = this.myHttpService.getCompanies()
        .pipe(
            concatAll(), // use this if your getCompanies() function returns Observable<Company[]> to get a single company
            mergeMap(company => this.myHttpService.getDepartments(company.id).pipe(
                map(departments => ({ company, departments })))
            ),
            toArray(), // here you receive {company: Company, departments: Department[]}[]
        );