我之前问过一个关于在使用闭包的 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/