我之前问过一个关于在使用闭包的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);
}
}
上面的代码(没有add和remove类)按预期工作 - 每秒播放一次音符。但是,我想要做的是在播放音符时也改变div的颜色,所以我在playNote()方法之前有addclass和removeclass。结果是笔记仍然可以正常运行,但是css更改不起作用 - 我认为正在发生的事情是添加和删除不会通过超时逻辑,因此在我注意到之前它被删除(因为它实际上在调试模式下工作)。
我想我不完全理解超时是如何工作的,所以如果有人能帮我解决上述代码,我会很感激。
更新: playNote()使用MIDI.js库播放钢琴音符:
function playNote(noteNumber){
var velocity = 127;
var delay = 0;
var instrumentChannel= 0;
MIDI.noteOn(instrumentChannel, noteNumber, velocity, delay);
}
答案 0 :(得分:3)
您的问题与超时无关:它与渲染引擎行为有关。
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);
}
}
答案 1 :(得分:0)
你也可以试试这个:
playAllNotes(0);
function playAllNotes(index) {
if(notes.length > index) {
setTimeout(function() {
$('mydiv').addClass('playing-note');
playNote(notes[index],index);
}, 1000);
}
}
function playNote(noteNumber,index){
var velocity = 127;
var delay = 0; var instrumentChannel= 0;
MIDI.noteOn(instrumentChannel, noteNumber, velocity, delay);
$('mydiv').removeClass('playing-note');
playAllNotes(index++);
}
答案 2 :(得分:0)
另一种方法
playAllNotes(0);
function playAllNotes(index) {
if(notes.length > index) {
setTimeout(function() {
$("mydiv").addClass("playing-note").delay(1000).queue(function(next){
$(this).removeClass("playing-note");
next();
});
playNote(notes[index]);
playAllNotes(index++);
}, 1000);
}
}