簡體   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