鉴于这两种时间都不会非常准确,一种setTimeout
更准确的方法是计算自上次迭代以来的延迟时间,然后适当调整下一次迭代。例如:
var myDelay = 1000;
var thisDelay = 1000;
var start = Date.now();
function startTimer() {
setTimeout(function() {
// your code here...
// calculate the actual number of ms since last time
var actual = Date.now() - start;
// subtract any extra ms from the delay for the next cycle
thisDelay = myDelay - (actual - myDelay);
start = Date.now();
// start the timer again
startTimer();
}, thisDelay);
}
所以第一次它会等待(至少)1000 毫秒,当你的代码被执行时,它可能会有点晚,比如 1046 毫秒,所以我们从下一个周期的延迟中减去 46 毫秒,下一个延迟将是仅 954 毫秒。这不会阻止计时器延迟触发(这是意料之中的),但可以帮助您阻止延迟堆积。(注意:您可能想要检查thisDelay < 0
这意味着延迟是目标延迟的两倍以上,并且您错过了一个周期 - 取决于您想如何处理这种情况)。
当然,这可能无法帮助您保持多个计时器同步,在这种情况下,您可能想弄清楚如何使用相同的计时器控制所有计时器。
所以看看你的代码,你所有的延迟都是 500 的倍数,所以你可以做这样的事情:
var myDelay = 500;
var thisDelay = 500;
var start = Date.now();
var beatCount = 0;
function startTimer() {
setTimeout(function() {
beatCount++;
// your code here...
//code for the bass playing goes here
if (count%2 === 0) {
//code for the chords playing goes here (every 1000 ms)
}
if (count%16) {
//code for the drums playing goes here (every 8000 ms)
}
// calculate the actual number of ms since last time
var actual = Date.now() - start;
// subtract any extra ms from the delay for the next cycle
thisDelay = myDelay - (actual - myDelay);
start = Date.now();
// start the timer again
startTimer();
}, thisDelay);
}