【问题标题】:Calling setTimeout in a loop not working as expected在循环中调用 setTimeout 未按预期工作
【发布时间】:2013-11-11 22:15:18
【问题描述】:

以下 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,Tom Swifty :)
  • 你能分享更多你的代码吗? notes 对象在哪里设置?
  • Tom Swifty,上面写着 JavaScript 的问题……还是在你问他之后他编辑了它……

标签: javascript loops settimeout


【解决方案1】:

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

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

【讨论】:

  • 为什么投票赞成?这将在每个循环上立即执行playNote()
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2021-09-12
      • 2020-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多