You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中异步循环未等待Promise完成的问题解决咨询

异步循环中数组未更新问题的解决方案

问题场景

我有一个名为srtHandler的异步函数,调用procureDuration获取MP3时长并推入script数组,但后续打印script时发现新值未被添加——尽管用了await,程序还是没等异步操作完成就继续执行了。

原代码片段:

const srtHandler = async (req, res) => {
  elements.forEach(async (num) => {
    const duration = await procureDuration(file, elementNames[num]);
    script[num].push(duration);
    console.log('>', script[num]);
    // 一堆其他操作
    console.log(script) // 这里显示script数组没更新
  });
};

const procureDuration = async (file, elementName) => {
  let duration = await getDuration(file, elementName);
    console.log({duration});
  return duration;
};

const getDuration = (subdirectory, file) => {
    console.log('getting duration of an MP3 file');
    const directoryPath = path.join(__dirname, `../data/${subdirectory}/${file}`);
    return new Promise((resolve, reject) => {
        mp3Duration(directoryPath, (err, duration) => {
            if (err) {
                console.log('error=', 'err');
                reject(err);
            } else {
                resolve(duration);
            }
        });
    });
};

问题根源

核心问题是**forEach不支持等待异步回调**。你传入的async (num) => {}会被当作独立的Promise,forEach会快速遍历完所有元素,完全不会等待每个回调里的await procureDuration执行完成。所以当你打印script时,大部分异步操作还在后台运行,数组自然没被更新。

解决方案

方案1:用for...of循环(顺序执行)

for...of是支持异步等待的循环结构,能确保每个异步操作完成后再执行下一次循环:

const srtHandler = async (req, res) => {
  // 遍历elements中的每个索引num
  for (const num of elements) {
    const duration = await procureDuration(file, elementNames[num]);
    script[num].push(duration);
    console.log('>', script[num]);
    // 一堆其他操作
    console.log(script); // 此时数组已更新
  }
};

方案2:用Promise.all结合map(并行执行,效率更高)

如果不需要严格按顺序执行异步操作,用这种方式可以让所有异步请求同时发起,大幅提升效率:

const srtHandler = async (req, res) => {
  // 将每个异步操作转为Promise,用Promise.all等待全部完成
  await Promise.all(elements.map(async (num) => {
    const duration = await procureDuration(file, elementNames[num]);
    script[num].push(duration);
    console.log('>', script[num]);
    // 一堆其他操作
  }));
  
  // 所有异步操作完成后再打印数组
  console.log(script);
};

内容的提问来源于stack exchange,提问作者Bragon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:01:20