在循环中调用 setTimeout 未按预期工作

Calling setTimeout in a loop not working as expected

本文关键字:工作 setTimeout 循环 调用      更新时间:2023-09-26

下面的JavaScript应该(在我看来)间隔0.5秒播放一系列音符。但它将它们全部作为单个同时和弦演奏。知道如何解决它吗?

function playRecording() {
    if (notes.length > 0) {
        for (var i = 0; i < notes.length; i++) {
            var timeToStartNote = 500 * i;
            setTimeout(playNote(i), timeToStartNote);
        }
    }
}
function playNote(i) {
    var noteNumber = notes[i];
    var note = new Audio("/notes/note_" + noteNumber + ".mp3");
    note.play();
}

JavaScript 闭包,将其包装在一个自执行函数中:

for (var i = 0; i < notes.length; i++) { 
    (function(i) {
       var timeToStartNote = 500 * i;
       setTimeout(function() {
           playNote(i)
       }, timeToStartNote);
    })(i)
}

谢谢大家,这是我问题的完整解决方案:

function playRecording() {
    if (notes.length > 0) {
        for (var i = 0; i < notes.length; i++) {
            playNote(i);
        }
    }
}
function playNote(i) {
    setTimeout(function () {
        var noteNumber = notes[i];
        var note = new Audio("/notes/note_" + noteNumber + ".mp3");
        note.play();
    }, 500 * i);
}

实际上非常简单,在 for 循环中,您调用函数 playNote(i) 它立即播放音符 i(因此像和弦一样立即演奏许多音符,因为它处于非常快速运行的 for 循环中)。相反,您应该尝试编写代码,让超时实际播放音符。setTimeout函数需要该函数作为参数,而不是您调用该函数。

(function(j){setTimeout(function(){playNote(j);},j*500);}(i));