【发布时间】:2010-10-27 13:24:05
【问题描述】:
我正在尝试用 Javascript 编写一个简单的音乐音序器。
声音将由SoundManager2播放
我很快意识到 setTimeout 和 setInterval 对于这种计时是没用的。他们的准确性根本不够好。
所以我正在尝试的是:
创建一个声音事件队列(一个二维数组 [ note, time ])
在while循环中处理队列
在伪代码中可能如下所示:
// The queue of time/note values (millisecs)
var q = [[0, C], [250, D], [500, E]]
var begin = (new Date).getTime()
while(q.length > 0 ){
var now = (new Date).getTime()
var eventTime = q[0][0] + begin
if( now >= eventTime){
playNote(q[0][1]) // Play the note
q.shift() // Now that the note has been played, discard it.
}
}
通过调试,我发现这个方法看起来足够精确(playNote 调用是在它应该的确切时间进行的)。
然而,在播放“序列”时,所有其他 Javascript(包括实际发出声音的位)都被暂停,这不足为奇。
这意味着我在运行序列所需的时间内保持沉默,然后执行所有对 playNote 的调用。
我尝试将while循环隔离在它自己的函数中,然后通过setTimeout调用它,希望这会创建一个后台线程来执行它自己的事情(即播放序列)而不会停止所有其他JS执行。那不行
我还尝试使用 setTimeout 调用 playNote 函数,希望虽然 UI 确实被冻结,但至少序列可以正确播放,但这也不起作用。
我也尝试了一种组合,但正如您可能已经猜到的那样,这也不起作用。
所以我的问题是:
如何在运行期间不关闭所有其他代码执行的情况下以精确的时间处理事件队列
【问题讨论】:
标签: javascript real-time