因为您依赖于触发事件,所以您无法在 getDuration 或 getVal 中返回值
相反,您想使用回调函数,像这样(回调)
该示例假设您希望将持续时间放入这样编写的跨度中
<span id="duration"></span>
function getDuration(src, cb) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
cb(audio.duration);
});
audio.src = src;
}
getDuration("./audio/2.mp3", function(length) {
console.log('I got length ' + length);
document.getElementById("duration").textContent = length;
});
任何需要“知道”长度的代码都应该在回调函数中(console.log 所在的位置)
使用承诺
function getDuration(src) {
return new Promise(function(resolve) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
resolve(audio.duration);
});
audio.src = src;
});
}
getDuration("./audio/2.mp3")
.then(function(length) {
console.log('I got length ' + length);
document.getElementById("duration").textContent = length;
});
使用事件 - 注意 'myAudioDurationEvent' 显然(几乎)可以是你想要的任何东西
function getDuration(src, obj) {
return new Promise(function(resolve) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
var event = new CustomEvent("myAudioDurationEvent", {
detail: {
duration: audio.duration,
}
});
obj.dispatchEvent(event);
});
audio.src = src;
});
}
var span = document.getElementById('xyz'); // you'll need to provide better logic here
span.addEventListener('myAudioDurationEvent', function(e) {
span.textContent = e.detail.duration;
});
getDuration("./audio/2.mp3", span);
虽然,这也可以通过回调或承诺类似地完成,方法是将目标传递给这些解决方案中的修改后的 getDuration 函数 - 我关于使用事件侦听器的观点更合适,例如,如果一个跨度被多次更新为持续时间- 这个解决方案仍然每个只跨越一次,所以可以很容易地用其他方法来实现
鉴于此答案的 cmets 中的新信息,我相信这是更好的解决方案
function getDuration(src, destination) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
destination.textContent = audio.duration;
});
audio.src = src;
}
然后像这样根据需要调用 getDuration
var span = createOrGetSomeSpanElement();
getDuration("./audio/2.mp3", span);
createOrGetSomeSpanElement 返回要在getDuration 函数中使用的目标元素 - 如何完成取决于您,当您在循环中创建播放列表时,我猜您创建了一些元素来接收已创建音频长度 - 有时很难回答半个问题