我正在给PokeApi打个电话,以获取Pokemon的列表。然后,我需要再次调用以返回每个神奇宝贝的精灵图像。
我能够使用rxjs Observables正确返回Pokemon的列表。当这返回神奇宝贝名称时,我再次调用神奇宝贝详细信息以返回精灵。但是,第二次调用不能及时完成以返回Pokemon Sprites。
public getListOfPokemon(page: number): Observable<Pokemon[]> {
let apiUrl = `${this.apiBaseUrl}/pokemon/?limit=1`;
if (page > 0) {
let offset = page * 42;
apiUrl = `${this.apiBaseUrl}/pokemon/?offset=${offset}&limit=42`;
}
return this._httpClient.get(apiUrl).pipe(
map((resp: any) => {
if (resp.results.length == 0) {
this.lastPageOfResults = resp.next == null;
this.router.navigate(['/404']);
}
this.lastPageOfResults = resp.next == null;
let pkmnList = _.map(resp.results, (pkmn) => {
let frontSprite: string;
let shinySprite: string;
new Promise(resolve => {
resolve(this.getPokemonSprites(pkmn.name).subscribe(sprite => {
return sprite;
}))
}).then((value) => {
console.log(value);
});
let singlePkmn = new Pokemon(pkmn.name, frontSprite, shinySprite);
return singlePkmn;
});
return pkmnList;
})
)
}
当我们返回新的神奇宝贝时,未设置frontSprite和shinySprite。
编辑 这是getPokemonSprites方法,用于进一步澄清
private getPokemonSprites(name: string): Observable<any> {
let apiUrl = `${this.apiBaseUrl}/pokemon/${name}`;
return this._httpClient.get(apiUrl).pipe(
map((pkmnDetail: any) => {
console.log('hi');
return pkmnDetail.sprites;
})
)
}
答案 0 :(得分:0)
发生这种情况是因为promise.then()
执行了异步操作。因此,当您返回new Pokemon()
时,可能不会始终设置精灵变量。因此,您需要等待异步操作完成。
因此,对于第二个映射,可以使用map
中的switchMap
而不是rxjs
来订阅内部可观察/链可观察。在switchMap
中,您可以将可观察变量数组与combineLatest
组合在一起,以得到可观察变量的响应数组。就像下面这样:
getPokemons = () => {
return this._httpClient.get(apiUrl).pipe(
map((resp: any) => {
if (resp.results.length == 0) {
this.lastPageOfResults = resp.next == null;
this.router.navigate(['/404']);
}
this.lastPageOfResults = resp.next == null;
return resp.results;
}),
switchMap((pokemonList) => {
const listOfObservables = [];
_.map(pokemonList, (pkmn) => {
let frontSprite: string;
let shinySprite: string;
const spriteObservable = this.getPokemonSprites(pkmn.name).pipe(
map((sprite) => {
let frontSprite = sprite.front_default;
let shinySprite = sprite.front_shiny;
return new Pokemon(pkmn.name, frontSprite, shinySprite);
})
)
listOfObservables.push(spriteObservable);
});
return combineLatest(listOfObservables);
})
)
}
然后,当您调用getPokemons
(我将其命名为显示用法)方法时,它将返回一个链式可观察的对象。订阅时,它返回一个Pokemon
的数组:
getPokemons.subscribe((pokemonList: Array<Pokemon>) => {
// do the fancy stuff with pokemonList array
})
希望这会有所帮助。
参考文献:
combine最新:https://www.learnrxjs.io/operators/combination/combinelatest.html
switchMap:https://www.learnrxjs.io/operators/transformation/switchmap.html