How to stop a setTimeout loop?

匿名 (未验证) 提交于 2019-12-03 08:59:04

问题:

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

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]?

回答1:

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.



回答2:

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


回答3:

You need to use a variable to track "doneness" and then test it on every iteration of the loop. If done == true then return.

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


回答4:

As this is tagged with the extjs tag it may be worth looking at the extjs method: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval

This works much like setInterval, but also takes care of the scope, and allows arguments to be passed too:

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

when you want to stop you can use clearInterval to stop it

clearInterval(bgPositionTimer); 

An example use case would be:

Ext.Ajax.request({     url: 'example.json',      success: function(response, opts) {         clearInterval(bgPositionTimer);     },      failure: function(response, opts) {         console.log('server-side failure with status code ' + response.status);         clearInterval(bgPositionTimer);     } }); 


回答5:

SIMPLIEST WAY TO HANDLE TIMEOUT LOOP

function myFunc (terminator = false) {     if(terminator) {         clearTimeout(timeOutVar);     } else {         // do something         timeOutVar = setTimeout(function(){myFunc();}, 1000);     } }    myFunc(true); //  -> start loop myFunc(false); //  -> end loop 


回答6:

I am not sure, but might be what you want:

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!