7

下面的 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();
}
4

3 回答 3

6

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

for (var i = 0; i < notes.length; i++) { 
    (function(i) {
       var timeToStartNote = 500 * i;
       setTimeout(function() {
           playNote(i)
       }, timeToStartNote);
    })(i)
}
于 2013-10-31T19:03:36.983 回答
4

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

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);
}
于 2013-10-31T19:39:35.213 回答
2

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

(function(j){setTimeout(function(){playNote(j);},j*500);}(i));
于 2013-10-31T18:55:01.837 回答