RxJs / Angular:通过地图循环内的订阅获取额外数据

RxJs / Angular: Fetch additional data via subscription inside a map loop

我是 angular 和 rxjs 的新手,我无法解决它。 我知道我的代码是错误的,但我不知道如何正确地写它。

我正在通过 HTTP 请求获取 JSON,JSON 包含数组中的数据。 之后我想遍历 JSON 数据中的数组并获取另一个 HTTP 端点的附加数据。

我查看了 flatMap、switchMap 等,但我无法在我的案例中组合这些命令。

谢谢大家!

到目前为止我的代码:

  checkMatches() {
    this.http.get<{
      message: string,
      result: any}>
    (BACKEND_URL + 'matches')
        .pipe(map((matchData) => {
          return {matches: matchData.result.map(match => {
            this.userService.getUserData(match.matchedUser).subscribe(userData => {
              console.log(userData);
            }
              );
            return {
              id: match._id,
              matchedUser: match.matchedUser,
              firstMatch: match.firstMatch,
              name: userData.userName,
              img: userData.userImg,
              status: match.status,
            };
          })};
        }))
        .subscribe(transformedMatchData => {
        console.log(transformedMatchData);
        });
  }

正如下面评论中提到的,你应该重新考虑这个架构,你应该有办法在 one/two 请求中获取所有这些记录,而不是触发 'N' 请求如果你的循环长度是 'N'.

回答原始发布的问题:

看来每一次匹配的响应,你都需要查询APIS,你可以在这里使用swicthMap()forkJoin:

使用 switchMap 会将 (BACKEND_URL + 'matches') say Parent observable url observable 与我们用它的结果创建的下一个 observable 合并,而且,如果 parent observable 再次发出,它会取消新的请求.

使用 forkJoin 会让您在发射数据之前等待所有子 Observable 完成。

checkMatches() {
    this.http.get<{
    message: string,
    result: any}>
    (BACKEND_URL + 'matches')
        .pipe(switchMap((matchData) => {
            return forkJoin(
                ...matchData.result.map(match => {
                    return this.userService.getUserData(match.matchedUser).pipe(
                        map((userData) => {
                            return {
                                id: match._id,
                                matchedUser: match.matchedUser,
                                firstMatch: match.firstMatch,
                                name: userData.userName,
                                img: userData.userImg,
                                status: match.status,
                            };
                        })
                    )
                })
            )
        }))
        .subscribe(transformedMatchData => {
            console.log(transformedMatchData);
        });
}