javascript - setTimeout 中的多个任务未按预期工作

标签 javascript css closures settimeout

我之前问过一个关于在使用闭包的 foreach 中使用 setTimeout 的问题: Javascript setTimeout in foreach: need help creating a closure

所选答案对我有用,但我现在遇到了不同的问题。这是我正在尝试做的事情:

playAllNotes(0);
function playAllNotes(index) {
    if(notes.length > index) {
        setTimeout(function() {
            $('mydiv').addClass('playing-note');
            playNote(notes[index]);
            $('mydiv').removeClass('playing-note');
            playAllNotes(index++);
        }, 1000);
    }
}

上面的代码(没有添加和删除类)按预期工作——每秒播放一次音符。但是,我想做的是在播放音符时也更改 div 的颜色,所以我在 playNote() 方法之前有 addclass ,在 playNote() 方法之后有 removeclass 。结果是音符仍然可以正常播放,但是 css 更改不起作用——我认为发生的事情是添加和删除没有经过超时逻辑,所以它在我注意到它之前就被删除了(因为它实际上确实在 Debug模式下工作)。

我想我并不完全理解超时是如何工作的,所以如果有人能帮助我修复上面的代码,我将不胜感激。

更新: playNote() 使用 MIDI.js 库来弹奏钢琴音符:

function playNote(noteNumber){
  var velocity = 127;
  var delay = 0;
  var instrumentChannel= 0;  
  MIDI.noteOn(instrumentChannel, noteNumber, velocity, delay);  
}

最佳答案

您的问题与超时无关:它与渲染引擎行为有关。

HTML 呈现是异步的:您添加了 playing-note 类,但它不会立即呈现。

但是,您的代码是同步的:您立即删除了 playing-note 类,并且在应用下一个渲染时...然后什么都没有改变。

您需要添加另一个超时来延迟类移除,并给人眼足够的时间来注意到变化。

例如:

playAllNotes(0);
function playAllNotes(index) {
    if(notes.length > index) {
        setTimeout(function() {
            $('mydiv').addClass('playing-note');
            playNote(notes[index]);
            // let say 250ms is enought for people to notice the change.
            setTimeout(function() {
                $('mydiv').removeClass('playing-note');
            }, 250);
            playAllNotes(index++);
        }, 1000);
    }
}

关于javascript - setTimeout 中的多个任务未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21957837/

相关文章:

emacs - 手动退出临时覆盖图

javascript - 使用 ajax 和 jQuery 发送 HTML 表单到 PHP

javascript - 即使在数组中也找不到对象

javascript - 从对象路径检索属性,如 data.#0.elements.#0.name"

HTML 单行文本,如果超过一行则附加 "..."?

css - 是否可以为 tabris 应用程序客户端设置主题?

rust - 修改并返回闭包

javascript - 使用多个选择选项的搜索功能 - angularjs

javascript - 找不到 Angular 2.2.0 平台浏览器动态 Bootstrap

javascript - 将类方法绑定(bind)到谷歌地图 v3 中的事件?