[英]How can I stop nested setTimeout with clearTimeout?
I have a function everyXsecsForYsecs
that will accept three arguments: a function, an interval time in seconds, and a total time in seconds.我有一个 function
everyXsecsForYsecs
,它将接受三个 arguments:一个 function,间隔时间(秒)和总时间(秒)。
everyXsecsForYsecs
should invoke the given function every X * 1000
milliseconds, yet then stop invoking the function after Y * 1000
milliseconds. everyXsecsForYsecs
应该每X * 1000
毫秒调用一次给定的 function,然后在Y * 1000
毫秒后停止调用 function。 Addition to this, here is a simple callback function for everyXsecsForYsecs
:除此之外,这里是 everyXsecsForYsecs 的简单回调
everyXsecsForYsecs
:
function sayHowdy(){
console.log('Howdy');
}
Then I call everyXsecsForYsecs
as such:然后我这样调用
everyXsecsForYsecs
:
everyXsecsForYsecs(sayHowdy, 1, 5);
So what I expect is to see 5 'Howdy' in the console, then function to stop.所以我希望在控制台中看到 5 'Howdy',然后 function 停止。 But what happens is that, function prints 'Howdy' for ever.
但发生的事情是,function 永远打印“你好”。 Here is how I implemented
everyXsecsForYsecs
,这是我实现
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);
}
I am suspicious about how I use clearTimeout
with nested setTimeout
, What I am missing exactly?我怀疑我如何将
clearTimeout
与嵌套的setTimeout
一起使用,我到底错过了什么?
By the time到......的时候
setTimeout(clearTimeout, y_mili, id);
runs, id
contains the timer id of the first outer setTimeout
call .运行时,
id
包含第一个外部setTimeout
调用的计时器 id。 Cancelling that won't really help.取消那将无济于事。 If you'd replace it with:
如果您将其替换为:
setTimeout(() => clearTimeout(id), y_mili);
it'll clear the timeout with the id
at that time , as you evaluate id
when the timeout is done , and not when it get's started .它会在那个时候用
id
清除超时,因为你在超时完成时评估id
,而不是在它开始时。
I'd write it as:我会把它写成:
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)
will call sayHowdy after 1000ms and store the timeout id within firstId
将在 1000 毫秒后调用 sayHowdy 并将超时 id 存储在 firstId 中
clearTimeout(firstId)
if this is called, the timeout referenced by the id will be cleared (no matter if it already is over or not)
如果调用了这个,id引用的超时将被清除(不管它是否已经结束)
But the question actually is, why you would want to clear the timeout, it's no interval, so you probably are in the wrong box.但问题实际上是,为什么你要清除超时,它没有间隔,所以你可能在错误的框中。
have a look at this snippet, it does not repeat for seconds, but x times with recursion:看看这个片段,它不会重复几秒钟,而是递归 x 次:
function fireAllXSecsYTimes(callback, fireAfterSeconds, counter) {
if (counter === 0) {
return;
}
setTimeout(() => {
callback();
counter--;
fireAllXSecsYTimes(callback, fireAfterSeconds, counter);
}, fireAfterSeconds * 1000)
}
what you asked for:你要求什么:
function fireAllXSecsForYSecs(callback, fireAfterSeconds, remainingSeconds) {
if (remainingSeconds <= 0) {
return;
}
setTimeout(() => {
callback();
fireAllXSecsForYSecs(callback, fireAfterSeconds, remainingSeconds - fireAfterSeconds);
}, fireAfterSeconds * 1000)
}
called with fireAllXSecsForYSecs(() => console.log('howdy'), 2, 5)
it will log 'howdy' 3 times, because on third execution, remainingSeconds
still has 1 left.用
fireAllXSecsForYSecs(() => console.log('howdy'), 2, 5)
调用它会记录 'howdy' 3 次,因为在第三次执行时, remainingSeconds
还剩下 1 个。 If you want to prevent this, just return if remainingSeconds <= 0 || remainingSeconds < fireAfterSeconds
如果你想防止这种情况,只要
remainingSeconds <= 0 || remainingSeconds < fireAfterSeconds
remainingSeconds <= 0 || remainingSeconds < fireAfterSeconds
Pass the reference not the value.传递引用而不是值。
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.