Javascript 如何使用clearTimeout停止嵌套的setTimeout?
我有一个函数Javascript 如何使用clearTimeout停止嵌套的setTimeout?,javascript,Javascript,我有一个函数everyXsecsForYsecs,它将接受三个参数:一个函数、以秒为单位的间隔时间和以秒为单位的总时间 everyXsecsForYsecs应每隔X*1000毫秒调用一次给定函数,但在Y*1000毫秒后停止调用该函数。除此之外,这里还有一个用于everyXsecsForYsecs的简单回调函数: function sayHowdy(){ console.log('Howdy'); } 然后我调用everyXsecsForYsecs,如下所示: everyXsecsForYs
everyXsecsForYsecs
,它将接受三个参数:一个函数、以秒为单位的间隔时间和以秒为单位的总时间
everyXsecsForYsecs
应每隔X*1000
毫秒调用一次给定函数,但在Y*1000
毫秒后停止调用该函数。除此之外,这里还有一个用于everyXsecsForYsecs
的简单回调函数:
function sayHowdy(){
console.log('Howdy');
}
然后我调用everyXsecsForYsecs
,如下所示:
everyXsecsForYsecs(sayHowdy, 1, 5);
因此,我期望在控制台中看到5个“Howdy”,然后函数停止。但实际情况是,函数永远打印“你好”。下面是我如何实现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);
}
将在1000毫秒后调用sayHowdy,并将超时id存储在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(回调、fireAfterSeconds、remainingSeconds){
如果(剩余)秒{
回调();
fireAllXSecsForYSecs(回调、fireAfterSeconds、remainingSeconds-fireAfterSeconds);
},fireAfterSeconds*1000)
}
使用fireAllXSecsForYSecs(()=>console.log('howdy'),2,5)调用
它将记录“howdy”3次,因为在第三次执行时,remainingSeconds
仍然还有1次。如果要防止出现这种情况,只需返回IfremainingSeconds传递引用而不是值
函数sayHowdy(){
console.log('Howdy');
}
函数everyXsecsForYsecs(回调,X,Y){
x_mili=x*1000;
y_mili=y*1000;
let id=setTimeout(函数运行(){
回调();
id=设置超时(运行,x_mili);
},x_mili);
setTimeout(()=>clearTimeout(id),y_mili);
//这里您需要传递对id的引用,而不是值
//这是不断变化的
}
每秒钟(sayHowdy,1,5)代码>谢谢你的回答,我犯的每一个基本错误。实际上,我这样做的唯一原因是能够使用嵌套超时并停止它。当然,您提供的代码片段也是一个合理的解决方案。谢谢。是的,我理解你的代码,你刚刚在y_mili之后清除了超时,但实际上你与x_mili的超时在这个时候已经运行了,所以不需要清除它。不客气。
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)
}