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

时间:2013-10-31 18:52:10

标签: javascript loops settimeout

以下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();
}

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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

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);
}

答案 2 :(得分:1)

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

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