在 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 类型或接口而不是 类。
有两个模型如下所示:
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
我在
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 类型或接口而不是 类。