如何停止setTimeout递归

时间:2019-05-14 11:22:32

标签: javascript recursion settimeout

我创建了一个setTimeout,它有一个名为run的回调。在运行中,我调用了console.log(i)以使用i++打印I的值,一旦它达到50,我想清除setTimeoutclearTimeout中,我通过运行使其递归再次调用setTimeout,但是它不起作用。 有人可以帮助我更好地理解这个概念吗?

let i = 1;

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

7 个答案:

答案 0 :(得分:1)

问题在于您的操作顺序。

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

如果我达到50,则将调用函数abc1()-清除间隔。

i++;
setTimeout(run,100);

在这里重新启动间隔。 您需要将其包装在else块中。

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

答案 1 :(得分:1)

let i = 1;

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

},100);

仅当计时器没有用完时,才应运行超时。

答案 2 :(得分:1)

调用setTimeout时,您将获得返回的计时器的ID。这正是您在这里所做的:

var abc = setTimeout(function run(){

但是,该ID仅在执行延迟功能之前才有效。一旦这样做,它是无效的。调用setTimeout(run,100);时,您将获得一个 new 计时器ID。您需要再次捕获它,否则ID将会丢失,并且您将无法停止它。

还有最后一个考虑因素-即使您是要正确捕获ID调用abc = setTimeout(run, 100);的当前代码,该ID仍将不停止计数器,因为它会尝试停止当前正在运行的函数(什么也不做),而不是取消下一个的执行:

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

为了停止执行,您有两个选择。如果您想使用最初的想法,则需要在计划完成后的 之后取消执行

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

或者,您可以完全不使用计时器句柄来执行此操作,而只需使用if条件来确定是否要安排另一个执行:

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

答案 3 :(得分:0)

run()中的setTimeout()未分配给任何变量,因此无法以任何方式清除它。

我想您想要覆盖abc,所以您必须替换:

setTimeout(run,100);

作者

abc = setTimeout(run,100);

答案 4 :(得分:0)

由于var abc仅设置了一次,因此在第一次超时时,您将只清除第一次超时,该超时很可能已经完成。

SetTimeout返回一个数字值,该数字值是引用该任务的ID。致电clearTimeout时,必须将要清除的超时通知ID,现在您要通知的是第一次超时的ID,该超时已经完成,因此无法清除。

如果您希望清除上一个超时,也许您希望始终使用每个超时的ID更新abc,如下所示:

 abc = setTimeout(run,100);

答案 5 :(得分:0)

这是执行定时循环的怪异方法,但您只需要清除(实际上不是在这种情况下,但是我还是喜欢这样做,因为一旦您不再使用它们,释放资源是一个好习惯)在创建新超时之前(通过跟踪abc句柄来完成),并在给定条件下clear之后返回:

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

答案 6 :(得分:0)

您需要在调用abc1函数后添加return。您清除超时,但代码仍在运行,然后再次调用setTimeout(run,100)。

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