解决数据拉取后Pokemon对象数组无法在外层正常访问的问题
解决异步请求未完成时无法获取数据的问题
你遇到的问题本质是**map里的异步函数不会阻塞代码执行**:当你在map外面遍历arrayOfPokemons时,里面的fetch请求还没全部完成,数组里自然没有数据。setTimeout能凑效是因为它延迟了执行,给了请求足够的时间完成,但这是不可靠的写法。下面是改写后的代码及思路说明:
第一步:简化fetchPokemonData函数
原代码把results塞进数组返回,导致后续需要取pokemonData[0],完全没必要,直接返回results数组即可:
const fetchPokemonData = async () => { const response = await fetch('https://pokeapi.co/api/v2/pokemon?limit=151'); const pokemonData = await response.json(); return pokemonData.results; // 直接返回结果数组,去掉不必要的嵌套 };
第二步:简化getPokemonsUrls函数
不用手动创建空数组再push,直接用map的返回值生成url数组:
const getPokemonsUrls = async () => { const pokemonData = await fetchPokemonData(); return pokemonData.map(pokemon => pokemon.url); // 直接映射出url数组,代码更简洁 };
第三步:修复createPokemonObject的异步逻辑
核心问题在这里:原代码用urls.map(async url => {})时,map会生成一个Promise数组,但你没有等待这些Promise全部完成就去遍历arrayOfPokemons。正确的做法是用Promise.all等待所有异步请求完成,直接得到填充好的数组:
const createPokemonObject = async () => { const urls = await getPokemonsUrls(); // 用map生成每个url对应的请求Promise,再用Promise.all等待全部完成 const arrayOfPokemons = await Promise.all(urls.map(async url => { const response = await fetch(url); const pokemon = await response.json(); // 解构并返回整理后的Pokemon对象 const { name, id, sprites: { other: { dream_world: { front_default } } }, types, weight, stats } = pokemon; return { name, id, image: front_default, types, weight, stats }; })); // 现在arrayOfPokemons已经是完整的数组,可以直接遍历操作 console.log(arrayOfPokemons); arrayOfPokemons.forEach(pokemon => console.log(pokemon)); return arrayOfPokemons; };
关键思路说明
- 去掉冗余嵌套:原
fetchPokemonData返回嵌套数组,增加了后续代码的复杂度,直接返回results数组更直观。 - 利用数组方法的返回值:
getPokemonsUrls里用map直接生成目标数组,避免手动操作空数组,代码更易读维护。 - 用
Promise.all处理批量异步:map结合async函数会返回Promise数组,Promise.all会等待所有Promise都完成后,返回包含所有结果的数组。这样就能保证在你遍历arrayOfPokemons时,所有数据都已经获取完成,不需要依赖setTimeout这种不可靠的延迟方案。
内容的提问来源于stack exchange,提问作者Marin
相关产品推荐
相关产品推荐

