6

可能是一个基本问题,但我有一个 Angular 应用程序,它调用后端服务来检索一些数据,然后使用该数据进行另一个后端服务调用。

第二个服务调用依赖于第一个成功完成,所以我使用了 RxJS 的 concatMap() 函数。

但是,我下面的代码仅返回第二次服务调用的数据。我需要从两个服务调用返回的所有数据。

有一种感觉,我搞砸了 .pipe 调用,但没有取得太大进展。提前致谢。

getData(id: String): Observable<any[]> {
return this.http.get<any>(`${this.baseUrl}/path/${id}`).pipe(
  concatMap(
    evt =>
      <Observable<any[]>>(
        this.http.get<any[]>(
          `${this.baseUrl}/path/relatedby/${evt.child_id}`
        )
      )
  ),
  retry(3),
  catchError(this.handleError("getData", []))
);}
4

3 回答 3

4

管道函数将给定的函数(作为参数提供)组合起来并按顺序执行它们,最后在经过各个阶段后返回最终输出。这就是为什么您只从第二次调用中获得结果的原因,因为那是管道中的最后一个函数(最后一个返回值的函数)。

例如:让我们看看这个

const filterOutEvens = filter(x => x % 2)
const double = map(value => value * 2);
const sum = reduce((acc, next) => acc + next, 0);

Observable.range(0, 10).pipe(
  filterOutEvens, 
  double, 
  sum)
 .subscribe(console.log); // 50

在这里,从 [1, 2, 3, 4, 5, 6 ,7, 8, 9,10],它首先过滤掉偶数,得到 [1,3,5,7,9],它被传递给next 函数(double),将给定数组的每个元素加倍,给出 [2,6,10,14,18],它被传递给管道中的下一个函数,即 sum(将数组中的元素相加) . sum 函数是 pipe 中的 LAST 函数,返回 50,这不仅是 sum() 的返回值,也是整个 pipe() 的返回值。

示例代码取自:https ://blog.hackages.io/rxjs-5-5-piping-all-the-things-9d469d1b3f44

编辑
如果你真的想要来自两个请求的数据,你可以使用'map'操作符将第一个请求的结果打包到第二个请求的结果中

 getData(id: String): Observable<any[]> {
  return this.http.get<any>(`${this.baseUrl}/path/${id}`).pipe(
 concatMap(
    evt =>
       <Observable<any[]>>(
          this.http.get<any[]>(
      `${this.baseUrl}/path/relatedby/${evt.child_id}`
        ).map(res =>( {"response1":evt, "response2":res}) )
  )
 ),
 retry(3),
 catchError(this.handleError("getData", []))
 );}
于 2018-07-16T21:59:43.150 回答
0

我在这里可能是错的,但双管道听起来没有必要。利用粗箭头语法括号进行隐式返回,我完成了这项工作。

this.$obs = this.route.params.pipe(
    concatMap((params: Params) => {
        console.log(params);
        return this.useParams(params.id)
    }),
    share() // irrelevant
);

让我知道是否对其他答案有警告。 #concatMapKindaRocks

于 2018-12-18T23:56:47.833 回答
0

谢谢,这很奏效,对管道的解释解决了我的很多问题。地图功能完美运行,尽管我只需要在另一个管道中敲击它。下面更新了代码,再次感谢您的帮助,非常感谢。

getData(id: String): Observable<any> {
return this.http.get<any>(`${this.baseUrl}/path/${id}`).pipe(
  concatMap(
    evt =>
      <Observable<any>>(
        this.http
          .get<any>(`${this.baseUrl}/path/relatedby/${evt.child_id}`)
          .pipe(
            map(resp => ({
              evtData: evt,
              childData: resp
            }))
          )
      )
  ),
  retry(3),
  catchError(this.handleError("getData", []))
);

}

于 2018-07-17T19:12:10.710 回答