在 rxjs operators 订阅之前修改 Observable 数组

Modify Observable array before subscribing by rxjs operators

有两个模型如下所示:

export class Game {
 id: number;
 name: string;
 platform: number;
}

export class Platform {
 id: number;
 name: string;
}

具有 Game 对象的可观察数组,该数组具有与 Platform 对象相关的 属性 platformId。为了更好地理解,我创建了两种单独的方法来获取我的游戏列表,以及另一种方法来获取基于 id 的平台。

getGames(): Observable<Game[]> {
    return of([
      {
        id: 1,
        name: 'god of war',
        platform: 1,
      },
      {
        id: 2,
        name: 'halo',
        platform: 2,
      },
    ]);
  }

  getPlatform(id): Observable<Platform> {
    if (id === 1)
      return of({
        id: 1,
        name: 'ps4',
      });

    if (id === 2)
      return of({
        id: 2,
        name: 'xbox',
      });
  }

现在我在 rxjs 的两个操作符(switchMap,forkJoin)的帮助下达到了这一点:

this.getGames()
      .pipe(
        switchMap((games: Game[]) =>
          forkJoin(
            games.map((game) =>
              forkJoin([this.getPlatform(game.platform)]).pipe(
                map(([platform]) => ({
                  game: game.name,
                  platform: platform.name,
                }))
              )
            )
          )
        )
      )
      .subscribe((v) => {
        console.log(v);
        this.gamesV2 = v;
      });

我的最终结果:

 [
     {
      game: "god of war"
      platform: "ps4"
     },
     {
      game: "halo"
      platform: "xbox"
     }
 ]

是否可以通过更简单的方式实现这一点? StackBlitz

我在 中找到了另一种方法,感谢 Daniel Gimenez 并将其放在这里,如果有人有更好更简单的方法,我非常感谢与我分享。 创建另一个方法,其中 returns 平台名称:

 getPlatformV2(id): Observable<string> {
    const platforms = [
      {
        id: 1,
        name: 'ps4',
      },
      {
        id: 2,
        name: 'xbox',
      },
    ];
    return of(platforms.find(x=>x.id===id).name);
  }
}

我没有使用两个 forkjoin,而是使用了 concatMap

this.getGames()
      .pipe(
        switchMap((games) => games),
        concatMap((game) =>
          forkJoin({
            game: of(game.name),
            platform: this.getPlatformV2(game.platform),
          })
        ),
        toArray()
      )
      .subscribe(console.log);

通过展平 getPlatformV2 的内部可观察数组:

this.getGames()
  .pipe(
    switchMap(games =>
      combineLatest(
        games.map(game =>
          this.getPlatformV2(game.id).pipe(
            map(platform => ({
              game: game.name,
              platform
            }))
          )
        )
      )
    )
  )

额外:关于游戏和平台,如果您不在这些类型或接口上实现构造函数,则应使用 TS 类型或接口而不是 类。