Javascript setTimeout?

So, I'm working on a music program that requires multiple javascript elements to sync to another. I use setInterval, which works very well initially, but over time, the elements gradually stop synchronizing, which is bad with a music program.

I read on the internet that setTimeout is more accurate, and you can somehow set setTimeout loops, however I did not find a generic version that illustrates how this is possible. Can someone just show me a basic example of using setTimeout for something endlessly.

Thank. Alternatively, if there is a way to achieve more synchronous results using setInterval or even another function, please let me know.

EDIT:

Basically, I have some functions like:

//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); 

At first it works very well, but within about a minute the sounds become noticeably out of sync, as I read with setInterval, I read that setTimeout can be more consistently accurate.

+68
javascript settimeout timing setinterval
03 Mar. '14 at 18:11
source share
10 answers

You can create a setTimeout loop using recursion:

 function timeout() { setTimeout(function () { // Do Something Here // Then recall the parent function to // create a recursive loop. timeout(); }, 1000); } 

The problem with setInterval() and setTimeout() is that there is no guarantee that your code will run at the specified time. Using setTimeout() and calling it recursively, you make sure that all previous operations in the timeout are completed before the next iteration of the code begins.

+148
Mar 03 '14 at 18:14
source share

For supplement only. If you need to pass a variable and repeat it, you can do this:

 function start(counter){ if(counter < 10){ setTimeout(function(){ counter++; console.log(counter); start(counter); }, 1000); } } start(0); 

Output:

 1 2 3 ... 9 10 

One line per second.

+22
Nov 16 '15 at 20:32
source share

Given that no time will be very accurate, one way to use setTimeout be a bit more accurate is to calculate how long the delay has been since the last iteration, and then adjust the next iteration accordingly. For example:

 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); } 

So, the first time it will wait (at least) 1000 ms, when your code will be executed, it may be a little late, say, 1046 ms, so we subtract 46 ms from our delay for the next cycle and the next delay will be only 954 ms This will not stop the timer from firing to the end (what to expect), but it will help you stop delays from recharging. (Note: you can check thisDelay < 0 , which means that the delay was more than twice the target delay, and you missed the loop - it's up to you how you want to deal with this case).

Of course, this probably will not help you synchronize multiple timers, in which case you may need to figure out how to manage them all with the same timer.

Thus, looking at your code, all your delays are a few 500, so you can do something like this:

 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); } 
+11
Mar 03 '14 at 18:26
source share

The best way to deal with audio synchronization is to use Web Audio Api, it has separate clocks that are accurate no matter what happens in the main stream. There is a great explanation here, examples, etc. from Chris Wilson:

http://www.html5rocks.com/en/tutorials/audio/scheduling/

Check out this site to learn more about the Web Audio API; it was designed to do exactly what you need.

+5
Apr 24 '15 at 3:10
source share

I use this method in my work: "Forget about common loops" in this case and use this combination of "setInterval", including "setTimeOut" s:

  function iAsk(lvl){ var i=0; var intr =setInterval(function(){ // start the loop i++; // increment it if(i>lvl){ // check if the end round reached. clearInterval(intr); return; } setTimeout(function(){ $(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond },50); setTimeout(function(){ // do another bla bla bla after 100 millisecond. seq[i-1]=(Math.ceil(Math.random()*4)).toString(); $("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]); $("#d"+seq[i-1]).prop("src",pGif); var d =document.getElementById('aud'); d.play(); },100); setTimeout(function(){ // keep adding bla bla bla till you done :) $("#d"+seq[i-1]).prop("src",pPng); },900); },1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions) } 

PS: Understand that the real behavior is (setTimeOut): they will all start at the same time “three bla bla bla will start counting at the same time”, so make another timeout to arrange the execution.

PS 2: an example of a synchronization loop, but for reaction loops you can use events promising asynchronous wait.

+1
Dec 01 '17 at 8:38 on
source share

SetTimeout loop task with solution

 // it will print 5 times 5. for(var i=0;i<5;i++){ setTimeout(()=> console.log(i), 2000) } // 5 5 5 5 5 // improved using let for(let i=0;i<5;i++){ setTimeout(()=> console.log('improved using let: '+i), 2000) } // improved using closure for(var i=0;i<5;i++){ ((x)=>{ setTimeout(()=> console.log('improved using closure: '+x), 2000) })(i); } 
0
Apr 18 '19 at 15:01
source share

Use setInterval()

 setInterval(function(){ alert("Hello"); }, 3000); 

Above alert("Hello"); will be executed alert("Hello"); every 3 seconds.

0
May 20 '19 at 21:42
source share

Use let instead of var in code:

 for(let i=1;i<=5;i++){setTimeout(()=>{console.log(i)},1000);} 
-one
Dec 05 '17 at 10:32
source share

I think it is better to end the timeout at the end of the function.

 function main(){ var something; make=function(walkNr){ if(walkNr===0){ // var something for this step // do something } else if(walkNr===1){ // var something for that step // do something different } // *** // finally else if(walkNr===10){ return something; } // show progress if you like setTimeout(funkion(){make(walkNr)},15,walkNr++); } return make(0); } 

These three functions are necessary because the vars in the second function will be overwritten each time with the default value. When the program pointer reaches the setTimeout value, one step has already been calculated. Then just the screen needs a little time.

-2
Jul 04 '14 at 11:15
source share

The following code works fine

 for (var i = 1; i <= 10; i++) <br>{ <br> setTimeout(function() { console.log(i); }, 1000*i); } 

Which gives you a result like 6 6 6 6 6

-3
Sep 26 '14 at 13:34
source share



All Articles