【发布时间】:2022-02-01 05:49:40
【问题描述】:
我正在使用 pokeapi 获取 151 个 pokemon 的数据。由于 API 没有获取所有 pokemon 的路由,因此我必须发送 151 个异步 get 请求(每个 pokemon 一个)。
尽管按顺序查询数据,但我注意到口袋妖怪是按随机顺序返回的,每次都以不同的顺序返回。我可以使用哪些策略来防止这种情况并按照请求的顺序排列它们(#1 - #151)?我假设这是由于请求的异步性质。 Async/await 可能有用,但我无法在这里成功实现。
pokedex.component.html:
<div class="container">
<div *ngFor="let pokemon of pokemons" class="pokemon-card">
<div>
<img src="{{ pokemon.sprites.front_default }}"/>
</div>
<span style="display:flex;">#{{pokemon.id}}</span>
<span>{{pokemon.name | titlecase}}</span>
</div>
</div>
pokedex.component.ts:
constructor(public _httpService: HttpService) { }
ngOnInit(): void {
this.getPokemon();
}
pokemons = [];
getPokemon() {
this._httpService.getPokemon().subscribe( async (data) => {
data.results.forEach((pokemon)=>{this.getPokemonDetails(pokemon.name)});
});
}
getPokemonDetails(pokemon) {
this._httpService.getPokemonDetails(pokemon).subscribe((data)=>{
this.pokemons.push(data);
});
}
http.service.ts:
constructor(private http: HttpClient) { }
pokemonsUrl = 'https://pokeapi.co/api/v2/pokemon';
getPokemon(): Observable<any> {
return this.http.get(`${this.pokemonsUrl}?limit=151`);
}
getPokemonDetails(name): Observable<any> {
return this.http.get(`${this.pokemonsUrl}/${name}`);
}
【问题讨论】:
-
试试这个:
this.pokemons[data.id - 1] = data;(而不是推送) -
上面的注释似乎是最简单的,只要记住处理ngFor中未定义的情况即可。
-
@ChrisG 这似乎可以解决问题,尽管现在我得到了像
ERROR TypeError: Cannot read properties of undefined (reading 'sprites')这样的控制台错误,即使精灵加载正确。为什么.push()以随机顺序构建数组,而使用array[data.id - 1]却保持正确顺序? -
问题在这里:
data.results.forEach((pokemon)=>{this.getPokemonDetails(pokemon.name)});你可以做的是使用“for of”语句并在其中等待。但这意味着每次只有一个请求。或者您记住索引并将其发送到 getPokemonDetails 以获取列表的正确索引。不过,您的编码方式可能不是最好的。尝试只使用一个订阅...请查看 switchMap、merge、combine ... 等。 -
您正在并行运行所有请求,因此它们将以任意顺序完成。这意味着您以任意顺序将它们推入数组。当您改用我的行时,每个对象都放在正确的索引处。这意味着该数组还将在其间获得一堆
undefined元素,直到各自的请求完成。正确的解决方案是使用Promise.all
标签: javascript angular typescript asynchronous rxjs