繁体   English   中英

如何使用 clearTimeout 停止嵌套的 setTimeout?

[英]How can I stop nested setTimeout with clearTimeout?

我有一个 function everyXsecsForYsecs ,它将接受三个 arguments:一个 function,间隔时间(秒)和总时间(秒)。

everyXsecsForYsecs应该每X * 1000毫秒调用一次给定的 function,然后在Y * 1000毫秒后停止调用 function。 除此之外,这里是 everyXsecsForYsecs 的简单回调everyXsecsForYsecs

function sayHowdy(){
  console.log('Howdy');
}

然后我这样调用everyXsecsForYsecs

everyXsecsForYsecs(sayHowdy, 1, 5);

所以我希望在控制台中看到 5 'Howdy',然后 function 停止。 但发生的事情是,function 永远打印“你好”。 这是我实现everyXsecsForYsecs的方式,

function everyXsecsForYsecs(callback, X, Y) {
  x_mili = X * 1000;
  y_mili = Y * 1000;

let id = setTimeout(function run(){
    callback();
    id = setTimeout(run, x_mili);
  }, x_mili);
setTimeout(clearTimeout, y_mili, id);
}

我怀疑我如何将clearTimeout与嵌套的setTimeout一起使用,我到底错过了什么?

到......的时候

 setTimeout(clearTimeout, y_mili, id);

运行时, id包含第一个外部setTimeout调用的计时器 id。 取消那将无济于事。 如果您将其替换为:

 setTimeout(() => clearTimeout(id),  y_mili);

它会在那个时候id清除超时,因为你在超时完成时评估id ,而不是在它开始时


我会把它写成:

 function everyXsecsForYsecs(callback, X, Y) {
   let count = Math.floor(Y / X);
   function recurring() {
      callback();
      if((count -= 1) >= 0)
        setTimeout(recurring, X * 1000);
  }
  setTimeout(recurring, X * 1000);
 }
let firstId = setTimeout(sayHowdy, 1000)

将在 1000 毫秒后调用 sayHowdy 并将超时 id 存储在 firstId 中

clearTimeout(firstId)

如果调用了这个,id引用的超时将被清除(不管它是否已经结束)

但问题实际上是,为什么你要清除超时,它没有间隔,所以你可能在错误的框中。

看看这个片段,它不会重复几秒钟,而是递归 x 次:

function fireAllXSecsYTimes(callback, fireAfterSeconds, counter) {
  if (counter === 0) {
    return;
  }
  setTimeout(() => {
    callback();
    counter--;
    fireAllXSecsYTimes(callback, fireAfterSeconds, counter);
  }, fireAfterSeconds * 1000)
}

你要求什么:

function fireAllXSecsForYSecs(callback, fireAfterSeconds, remainingSeconds) {
  if (remainingSeconds <= 0) {
    return;
  }
  setTimeout(() => {
    callback();
    fireAllXSecsForYSecs(callback, fireAfterSeconds, remainingSeconds - fireAfterSeconds);
  }, fireAfterSeconds * 1000)
}

fireAllXSecsForYSecs(() => console.log('howdy'), 2, 5)调用它会记录 'howdy' 3 次,因为在第三次执行时, remainingSeconds还剩下 1 个。 如果你想防止这种情况,只要remainingSeconds <= 0 || remainingSeconds < fireAfterSeconds remainingSeconds <= 0 || remainingSeconds < fireAfterSeconds

传递引用而不是值。

 function sayHowdy() { console.log('Howdy'); } function everyXsecsForYsecs(callback, X, Y) { x_mili = X * 1000; y_mili = Y * 1000; let id = setTimeout(function run() { callback(); id = setTimeout(run, x_mili); }, x_mili); setTimeout(() => clearTimeout(id), y_mili); //here you need to pass the reference to the id not the value //which is constantly changing } everyXsecsForYsecs(sayHowdy, 1, 5);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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