Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 一行调用两次setTimeout()函数_Javascript_Node.js - Fatal编程技术网

Javascript 一行调用两次setTimeout()函数

Javascript 一行调用两次setTimeout()函数,javascript,node.js,Javascript,Node.js,我正在编写一个机器人,它以可变的间隔发送警报。我正在使用setTimeout(),但我似乎无法解决一个问题。(简化)代码为: 示例输入为: 输入的第一个输入:从现在起5分钟内每隔8小时设置一次警报(“呼叫鲍勃”) 输入第二个输入:从现在起4分钟开始,每8小时设置一次警报(“呼叫Jane”) 在4分钟内,我正确地得到了“call Jane”(这个是从bot代码中设置的) 一分钟后,我正确地得到了“call Bob”,但我也得到了“call Jane”(这应该在8小时后才会发生) 我打印了所有的超时

我正在编写一个机器人,它以可变的间隔发送警报。我正在使用setTimeout(),但我似乎无法解决一个问题。(简化)代码为:

示例输入为: 输入的第一个输入:从现在起5分钟内每隔8小时设置一次警报(“呼叫鲍勃”)

输入第二个输入:从现在起4分钟开始,每8小时设置一次警报(“呼叫Jane”)

在4分钟内,我正确地得到了“call Jane”(这个是从bot代码中设置的) 一分钟后,我正确地得到了“call Bob”,但我也得到了“call Jane”(这应该在8小时后才会发生)

我打印了所有的超时值,它们看起来都是正确的。我还在issueAlarm()函数中打印setTimeout()函数的返回值

在第一次呼叫中:_idleTimeout:59994(这是正确的,下一次呼叫在一分钟后)

在第二次通话中:_idleTimeout:28739994(这看起来是正确的,大约是8小时,但我仍然马上接到第三次通话)

在第三个调用中:_idleTimeout:28799991(此超时看起来正确,但此函数调用不应发生)

我使用的是僵尸网络框架。我对JavaScript和node.js的了解还远远不够。我已经把我能想到的一切都打印出来了,但我不明白为什么第三个电话会马上打出来


仅当输入的第一个输入请求的警报比在第二个输入中输入的警报晚启动时,才会发生这种情况。但我不可能理解为什么

我想下一个返回数据的函数可能会有问题,看看我的例子。如果您的函数在保存下一个元素时返回该元素,则无法使用该函数,您需要构建一个返回要调用的第一个报警的函数。希望有帮助

var dh={};
dh.alarms=[{time:1000,name:“Jane”},{time:5000,name:“Jane”},{time:3000,name:“Bob”}];
dh.first=函数(){
dh.alarms=dh.alarms.sort(函数(a,b){返回a.time-b.time});
next=dh.alarms.slice(0,1);
dh.alarms=dh.alarms.slice(1);
返回下一步[0]
}
dh.next=函数(){
next=dh.alarms.slice(0,1);
dh.alarms=dh.alarms.slice(1);
返回下一步[0]
}
var timeout=setTimeout(executeAlarm,299999);
函数start(){
var next=dh.first();//dh.next();我以为这是你的问题!!
if(next&&next.name){
清除间隔(超时);
timeout=setTimeout(函数(){executeAlarm(next)},next.time);
}
}
函数executeAlarm(下一步){
如果(!next | |!next.name)清除间隔(超时)
document.getElementById(“报警”).innerHTML+=“报警为”+next.name+”;
start();
}
document.addEventListener(“DOMContentLoaded”,start,false)
(代表OP发布)

问题就在这里,在bot代码中:

if (nextD.timestamp >= mom.valueOf() ){
        var now = new Date();        
        clearTimeout(timeout);
        timeout = mom.valueOf() - now;
        setTimeout(issueAlarm, timeout);
        }
我第一次正确地清除了超时(当我清除2^31-1的原始超时时),但之后没有。问题是我调用setTimeout的行应该是

timeout = setTimeout(issueAlarm, timeout);
因此,返回值存储在超时对象中。我随后通过传递一个值而不是一个对象来调用clearTimeout(),因此第一次存储的超时(5分钟,“调用Bob”)从未被清除


感谢@guest271314和@damianfabian帮助我获得正确答案。

timeout
的引用从
setTimeout
更改为
timeout=mom.valueOf()-现在
timeout=peek.timestamp-now?@Piwwoli:我已尝试清除超时。它不起作用。我在这里打印setTimeout函数返回的间隔。正如我所说,在将值传递给函数之前,我还打印了这些值。他们是correct@guest271314:我就是这样改变间隔的。我最初使用'timeout'变量,以便在用户输入他们想要的警报时间时清除间隔超时。然后,在issueAlarm()内部,我可以直接调用:setTimeout(issueAlarm,peek.timestamp now),而不是将其传递给timeout(还尝试了一个局部变量),但我这样保存它,因为这样更容易debug@guest271314:如果第二个输入计划早于第一个输入(不起作用的情况),则不适用。为什么?@guest271314:我不知道你为什么问这个问题,但最终,在思考了很多如果我只打一次电话为什么会奏效之后,我发现了问题所在。非常感谢。谢谢你的回复。但是正如我所说(以及setTimeout()返回的值),元素被正确地检索到。报警存储在优先级队列中,因此,第一个元素总是最小的(假设是最小堆,并且元素被正确排序)。另外,第三个警报在第二个警报后立即运行,因为我对上面的一条评论很感兴趣,我在bot代码中只调用了一次clearTimeout()(而不是每次添加新的“较小”元素时都调用它)。这似乎有效,但我仍然不知道为什么,我不能真正使用它。看看你的代码流是这样的:1-ClearInterval和setTimeout in 1分钟(Jane)2-从setTimeout调用到1分钟(Bob)3-Jane alarm立即再次触发。这是因为你没有清理第一个超时。如果您在我的代码中看到,每次调用start函数时,我都会使用clearInterval。正如我在上面的一条评论中所说的,我已经尝试在issueAlarm的主体中使用clearTimeout(),但没有任何更改。无论如何,一旦函数被调用,就不需要清除超时,只有当函数还没有被调用并且您想要更改它时,这就是我在bot代码中所做的。在bot代码中只调用一次clearTimeout()是唯一改变任何事情的方法。解决它吧!它与清除超时有关,但不是在函数本身中,而是在bot代码中。用我的发现更新了这个问题,非常感谢您花时间(因为它是在确保clearTimeout()正确的情况下完成的)
timeout = setTimeout(issueAlarm, timeout);