Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop a setTimeout loop?

I'm trying to build a loading indicator with a image sprite and I came up with this function

function setBgPosition() {    var c = 0;     var numbers = [0, -120, -240, -360, -480, -600, -720];     function run() {        Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');         if (c<numbers.length)         {             setTimeout(run, 200);         }else         {             setBgPosition();         }     }     setTimeout(run, 200); } 

so the out put is looks like this

http://jsfiddle.net/TTkre/

I had to use setBgPosition(); inside else to keep this running in a loop so now my problem is how to stop this loop once I want [load finished]?

like image 551
Gihan Lasita Avatar asked Dec 09 '11 08:12

Gihan Lasita


People also ask

How do you stop a setTimeout?

To cancel a setTimeout() method from running, you need to use the clearTimeout() method, passing the ID value returned when you call the setTimeout() method.

Can you pause setTimeout?

Working with asynchronous functions setTimeout() is an asynchronous function, meaning that the timer function will not pause execution of other functions in the functions stack. In other words, you cannot use setTimeout() to create a "pause" before the next function in the function stack fires.

How do I stop setTimeout in react?

Clearing setTimeout A setTimeout timer must be cleared and handle properly, otherwise, you may experience adverse side effects in your code. To clear or cancel a timer, you call the clearTimeout(); method, passing in the timer object that you created into clearTimeout().

Does setTimeout run forever?

The setTimeout() is executed only once. If you need repeated executions, use setInterval() instead.


2 Answers

setTimeout returns a timer handle, which you can use to stop the timeout with clearTimeout.

So for instance:

function setBgPosition() {     var c = 0,         timer = 0;     var numbers = [0, -120, -240, -360, -480, -600, -720];     function run() {         Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');         if (c >= numbers.length) {             c = 0;         }         timer = setTimeout(run, 200);     }     timer = setTimeout(run, 200);      return stop;      function stop() {         if (timer) {             clearTimeout(timer);             timer = 0;         } } 

So you'd use that as:

var stop = setBgPosition(); // ...later, when you're ready to stop... stop(); 

Note that rather than having setBgPosition call itself again, I've just had it set c back to 0. Otherwise, this wouldn't work. Also note that I've used 0 as a handle value for when the timeout isn't pending; 0 isn't a valid return value from setTimeout so it makes a handy flag.

This is also one of the (few) places I think you'd be better off with setInterval rather than setTimeout. setInterval repeats. So:

function setBgPosition() {     var c = 0;     var numbers = [0, -120, -240, -360, -480, -600, -720];     function run() {         Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');         if (c >= numbers.length) {             c = 0;         }     }     return setInterval(run, 200); } 

Used like this:

var timer = setBgPosition(); // ...later, when you're ready to stop... clearInterval(timer); 

All of the above notwithstanding, I'd want to find a way to make setBgPosition stop things itself, by detecting that some completion condition has been satisfied.

like image 198
T.J. Crowder Avatar answered Oct 12 '22 19:10

T.J. Crowder


I know this is an old question, I'd like to post my approach anyway. This way you don't have to handle the 0 trick that T. J. Crowder expained.

var keepGoing = true;  function myLoop() {     // ... Do something ...      if(keepGoing) {         setTimeout(myLoop, 1000);     } }  function startLoop() {     keepGoing = true;     myLoop(); }  function stopLoop() {     keepGoing = false; } 
like image 35
ThimoKl Avatar answered Oct 12 '22 21:10

ThimoKl