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

仅在加载指定音频数据后重新执行while循环的实现问题

问题根因

你的推测是正确的,还有几处额外的问题共同导致了当前结果:

  • 同步执行的while循环不会等待异步的loadedmetadata事件触发,循环会在毫秒级跑完所有迭代,所有音频加载请求几乎同时发出
  • 全局复用同一个audio元素,每次修改src会覆盖上一个资源地址,事件触发时读取的au.duration永远是最后一个加载完成的音频的时长
  • 事件回调存在闭包问题,回调执行时循环变量i已经迭代到最终值,无法和每个音频一一对应

解决方法

我们可以把单个音频时长获取逻辑封装成Promise,配合async/await实现串行加载,保证上一个音频加载完成、拿到时长后再进入下一轮迭代:

const myList = [
  'https://mixergy.com/wp-content/audio/Nick-Bolton-Animas-on-Mixergy0721.mp3',
  'https://episodes.castos.com/5e7027dcc7b720-84196812/MicroCOnf-on-Air-Refresh.Ep.6.mp3'
];
// 存储所有音频时长的数组
const audioDurations = [];

// 封装单个音频时长获取的Promise
function getAudioDuration(url) {
  return new Promise((resolve, reject) => {
    const au = document.createElement('audio');
    au.src = url;
    // 元数据加载成功后返回时长
    au.addEventListener('loadedmetadata', () => {
      const duration = Math.round(au.duration);
      resolve(duration);
    }, false);
    // 加载失败的兜底
    au.addEventListener('error', (err) => {
      reject(err);
    }, false);
  })
}

// 串行加载所有音频获取时长
async function loadAllAudioDurations() {
  for(let i = 0; i < myList.length; i++) {
    try {
      const duration = await getAudioDuration(myList[i]);
      audioDurations.push(duration);
      console.log(`第${i+1}个音频时长:${duration}秒`);
    } catch(e) {
      console.log(`第${i+1}个音频加载失败:`, e);
      audioDurations.push(null);
    }
  }
  // 所有音频加载完成后输出总结果
  console.log('所有音频时长:', audioDurations);
}

// 执行加载逻辑
loadAllAudioDurations();

你原有HTML代码不需要做任何修改,直接替换JS文件的逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:39:03