如何用async/await在jQuery的loadedmetadata中同步获取音频时长
修复jQuery结合await获取音频时长的异步顺序问题
你当前代码的核心问题是**await $(audio).on(...)无法等待loadedmetadata事件触发**——jQuery的on()方法返回的是jQuery对象,不是Promise,await对它完全无效,所以getAudioUrlDuration会立刻执行完毕,导致后续的333、444先弹出,等音频元数据加载完成后才会触发回调弹出222。
要实现你期望的同步顺序,需要把getAudioUrlDuration改成返回Promise,让await能正确等待事件完成。修复后的代码如下:
function callBackFun3(leng){ alert('222 leng='+leng) ; } var src = "https://www.w3schools.com/tags/horse.mp3" ; // 改造为返回Promise的函数 async function getAudioUrlDuration(src, callBackFun) { return new Promise((resolve) => { var audio = new Audio(); audio.src = src; // 监听元数据加载完成事件 $(audio).on("loadedmetadata", function(){ if (callBackFun) { callBackFun(audio.duration); } // 把duration作为Promise的返回值 resolve(audio.duration); }); }); } async function aaa(){ alert(111); // await获取Promise返回的duration const duration = await getAudioUrlDuration(src, callBackFun3); alert( '333 duration='+duration ) ; alert(444); } aaa();
关键改动说明:
- 让
getAudioUrlDuration返回一个Promise,在loadedmetadata事件触发时通过resolve返回音频时长,确保await能等待事件完成 - 移除全局的
duration变量,直接通过await接收返回值,避免全局变量污染 - 保留原有的回调函数
callBackFun3,确保222的弹窗逻辑不变
现在执行代码,alert顺序会完全符合你的预期:
- 111
- 222 leng=1.549188
- 333 duration=1.549188
- 444
内容的提问来源于stack exchange,提问作者user2818066
相关产品推荐
相关产品推荐

