use*_*366 78 javascript timing settimeout setinterval
所以我正在制作一个音乐程序,需要多个javascript元素与另一个同步.我一直在使用setInterval,它最初工作得非常好但是随着时间的推移,元素逐渐变得不同步,而音乐程序则很糟糕.
我在网上看到setTimeout更准确,你可以用某种方式设置setTimeout循环但是我还没有找到一个通用版本来说明这是如何实现的.有人可以向我展示一个使用setTimeout无限循环的基本示例.
谢谢.或者,如果有办法通过setInterval或其他功能实现更多同步结果,请告诉我.
编辑:
基本上我有一些像这样的功能:
//drums
setInterval(function {
//code for the drums playing goes here
},8000);
//chords
setInterval(function {
//code for the chords playing goes here
},1000);
//bass
setInterval(function {
//code for the bass playing goes here
},500);
Run Code Online (Sandbox Code Playgroud)
它最初工作得非常好,但是在大约一分钟的过程中,声音明显不同步,因为我已经阅读了setInterval,我读过setTimeout可以更加一致地准确.
War*_*0ck 160
您可以setTimeout使用递归创建循环:
function timeout() {
setTimeout(function () {
// Do Something Here
// Then recall the parent function to
// create a recursive loop.
timeout();
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
这个问题setInterval()和setTimeout()是没有保证你的代码将在指定时间运行.通过setTimeout()递归使用和调用它,您可以确保在下一次代码迭代开始之前,超时内的所有先前操作都已完成.
Joã*_*ulo 27
只是补充.如果你需要传递一个变量并迭代它,你可以这样做:
function start(counter){
if(counter < 10){
setTimeout(function(){
counter++;
console.log(counter);
start(counter);
}, 1000);
}
}
start(0);
Run Code Online (Sandbox Code Playgroud)
输出:
1
2
3
...
9
10
Run Code Online (Sandbox Code Playgroud)
每秒一行.
Mat*_*and 11
假设两个时间都不准确,使用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);
}
Run Code Online (Sandbox Code Playgroud)
所以它第一次等待(至少)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);
}
Run Code Online (Sandbox Code Playgroud)
小智 7
处理音频定时的最佳方法是使用Web Audio Api,它有一个单独的时钟,无论主线程发生什么,都是准确的.克里斯威尔逊在这里有一个很好的解释,例子等:
http://www.html5rocks.com/en/tutorials/audio/scheduling/
浏览一下这个网站以获取更多的Web Audio API,它的开发完全符合您的要求.
setInterval(function(){
alert("Hello");
}, 3000);
Run Code Online (Sandbox Code Playgroud)
上面的代码每 3 秒执行一次alert("Hello");。
根据您的要求
只是给我看一个使用 setTimeout 循环的基本例子
我们有以下示例可以帮助您
var itr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var interval = 1000; //one second
itr.forEach((itr, index) => {
setTimeout(() => {
console.log(itr)
}, index * interval)
})Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
178070 次 |
| 最近记录: |