简体   繁体   中英

how to stop the setTimeout recursion

I have created the setTimeout which has a callback named run, Inside the run I have called a console.log(i) to print the value of I with i++ and once it reaches to 50, I want to clear the setTimeout with clearTimeout , I am calling setTimeout again with run making it recursive, but it doesn't work. can somebody help me understand the concept better?

let i = 1;

var abc = setTimeout(function run(){
   console.log(i);
if(i==50){
    abc1();
  }  
  i++;
  setTimeout(run,100);
},100);
function abc1(){
     clearTimeout(abc);
}

When you call setTimeout you get the ID of the timer returned. It's exactly what you've done here:

var abc = setTimeout(function run(){

However, that ID is valid only until the delayed function executes. Once it does, it's ineffective. When you call setTimeout(run,100); you will get a new ID for the timer. You need to capture that again, otherwise the ID gets lost and you have no way to stop it.

There is a final consideration - with your current code even if you were to correctly capture the ID calling abc = setTimeout(run, 100); that would still not stop the counter because it will attempt to stop the function that is running right now (which does nothing), instead of cancelling the execution of the next one:

let i = 1;

var abc = setTimeout(function run() {
  console.log(i);
  if (i == 50) {
    abc1(); //this will clear the *current* timer 
  } 
  i++;
  abc = setTimeout(run, 100); //this will set the *new* ID 

}, 100);

function abc1() {
  clearTimeout(abc);
}

In order to stop the execution you have two options. If you want to use your initial idea, you need to cancel the future execution after it is scheduled

 let i = 1; var abc = setTimeout(function run() { console.log(i); abc = setTimeout(run, 100); //this will set the *new* ID if (i == 50) { abc1(); //this will clear the *new* timer now } i++; }, 100); function abc1() { clearTimeout(abc); } 

Alternatively, you can do it without using timer handles at all and just use the if condition to determine if you want to schedule another execution or not:

 let i = 1; setTimeout(function run() { console.log(i); if (i != 50) { //until 50 is reached abc = setTimeout(run, 100); //schedule a new execution } i++; }, 100); 

The problem is the order of your operations.

if(i==50){
    abc1();
  } 

If i reaches 50, the function abc1() will be called - which clears the interval.

i++;
setTimeout(run,100);

here you're restarting the interval. You need to wrap it inside an else block.

 let i = 1; var abc = setTimeout(function run() { console.log(i); if (i == 50) { abc1(); } else { i++; setTimeout(run, 100); } }, 100); function abc1() { clearTimeout(abc); } 

let i = 1;

var abc = setTimeout(function run(){
  console.log(i);
  if(i<50){
      setTimeout(run,100);
    }  
  i++;

},100);

You should run timeout only if timer not run out.

The setTimeout() inside run() in not assigned to any variable so it can't be cleared in any manner.

I suppose what you want is to overwrite abc so you must replace:

setTimeout(run,100);

by

abc = setTimeout(run,100);

Since var abc is only set once, at the first timeout, you are clearing only the very first Timeout, which very likely is already complete.

SetTimeout returns a numeric value, which is an ID to refer to that task. When you call clearTimeout , you must inform the ID of the timeout you want to clear, and now you are informing the ID for the very first timeout, which is already finished, thus can't be cleared.

If you wish to clear the last timeout, maybe you would like to always update abc with the IDs for each timeout, like this:

 abc = setTimeout(run,100);

This is a weird way of doing a timed loop but you just need to clear (actually not in this case but I like to do it anyway as it is a good practice to release resources once you don't use them anymore) the timeouts (done by keeping track of abc handle) before creating new ones and return after clear on the given condition:

 let i = 1; let abc = setTimeout( function run(){ console.log(i); if(i==50){ abc1(); return; } abc1(); i++; abc = setTimeout(run,100); }, 100 ); function abc1(){ clearTimeout(abc); } 

you need to add return after you call abc1 function. you clear timeout, but then code still running and call setTimeout(run,100) again.

        let i = 1;

var abc = setTimeout(function run(){
   console.log(i);
if(i==50){
    abc1();
    return;
  }  
  i++;
  setTimeout(run,100);
},100);
function abc1(){
     clearTimeout(abc);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM