Ruby开发者求助:JS异步函数循环填充数组返回空数组问题
解决异步函数返回空数组的问题
嘿,我明白你现在的困扰——从Ruby转过来,JavaScript的异步逻辑确实容易让人摸不着头脑!你的问题其实是典型的没有等待所有异步操作完成就返回结果,我来一步步给你拆解和解决:
为什么会返回空数组?
你在循环里调用asynchronously_fetch_sound(a)并绑定了.then回调,但这些异步操作都是“发起后就不管”的状态——循环会快速执行完所有迭代,直接走到return sounds这一行,而此时所有的Promise还没来得及完成解析,所以数组自然是空的。
解决方案1:循环内使用await(串行请求)
如果你的API不支持并行请求,或者你需要按顺序获取结果,可以在循环里用await暂停函数执行,直到当前Promise完成:
async function getAnimalSounds(animals){ var sounds = [] for (const a of animals){ // 等待当前异步请求完成,再继续下一次循环 const result = await asynchronously_fetch_sound(a); sounds.push(result); } return sounds; // 现在会等所有请求完成后再返回 }
这种方式下,每一次动物的声音请求都会等上一个完成后才发起,适合有严格顺序要求的场景。
解决方案2:用Promise.all并行请求(更高效)
如果API允许并行调用,Promise.all是更优的选择——它可以同时发起所有请求,等全部完成后一次性返回结果数组,速度更快:
async function getAnimalSounds(animals){ // 先把每个动物对应的异步请求Promise收集到数组中 const soundPromises = animals.map(animal => asynchronously_fetch_sound(animal)); // 等待所有Promise解析完成,结果会按原数组顺序返回 const sounds = await Promise.all(soundPromises); return sounds; }
注意:调用异步函数也要等待结果
因为getAnimalSounds是async函数,它本身返回的也是一个Promise,所以你调用它的时候,也要用await或者.then来获取最终结果:
// 示例调用方式1:用await(需要在async函数内) async function main() { const animalSounds = await getAnimalSounds(['dog', 'cat', 'bird']); console.log(animalSounds); // 这里就能拿到填充完成的数组了 } main(); // 示例调用方式2:用.then回调 getAnimalSounds(['dog', 'cat', 'bird']).then(sounds => { console.log(sounds); });
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

