繁体   English   中英

setTimeout()函数连续两次调用

[英]setTimeout() function being called twice in a row

我正在编写一个以可变间隔发送警报的机器人。 我正在使用setTimeout(),我有一个我似乎无法弄清楚的问题。 (简化)代码是:

//Original call to setTimeout():

timeout = setTimeout(issueAlarm, 2147483647); // highest possible interval setTimeout() will accept. 

//In bot:
// dh is a priority queue that keeps timestamps sorted from smaller to larger as the user requests alerts. 
//'mom' is a moment.js variable that holds the most recent request. 
//This block of code checks the PQ and if what the user just entered is smaller than what is already stored, it updates the timeout. 
//This seems to work fine
// First get input from user and store the desired time of first alert in 'mom'. Then:
var nextD = dh.peekNext();
if (nextD.timestamp >= mom.valueOf() ){
    var now = new Date();        
    clearTimeout(timeout);
    timeout = mom.valueOf() - now;
    setTimeout(issueAlarm, timeout);
    }

//issueAlarm function:

function issueAlarm() {
    var next = dh.getNext(); // this pops the first alarm from the queue
    // here goes some code that issues message. Then:
    var peek = dh.peekNext(); // this looks at the next element in the queue without popping it
    if (peek) {
        var now = new Date();
        timeout = peek.timestamp - now;
        setTimeout(issueAlarm, timeout);
        }
    }

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

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

在4分钟内,我正确地得到“呼叫简”(这个从机器人代码中获取)一分钟后,我正确地得到“呼叫鲍勃”,但我也得到“呼叫简”(这应该在8小时后才会发生) )

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

在第一个电话里面:_idleTimeout:59994(这是正确的,下一个电话是在一分钟内)

在第二个电话里面:_idleTimeout:28739994(这看起来很正确,大约8个小时,但我仍然可以立即收到第三个电话)

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

我正在使用botFramework。 我对JavaScript和node.js的了解远非广泛。 我已经打印出了我能想到的一切,但我无法弄清楚为什么第三次电话会立刻被制作出来。

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

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

 var dh = {}; dh.alarms = [{time: 1000, name:"Jane"},{time:5000, name:"Jane"},{time: 3000, name:"Bob"}]; dh.first = function(){ dh.alarms = dh.alarms.sort(function(a,b){return a.time - b.time}); next = dh.alarms.slice(0,1); dh.alarms = dh.alarms.slice(1); return next[0] } dh.next = function(){ next = dh.alarms.slice(0,1); dh.alarms = dh.alarms.slice(1); return next[0] } var timeout = setTimeout(executeAlarm, 2999999); function start(){ var next = dh.first(); // dh.next(); I thought this is your problem!! if(next && next.name){ clearInterval(timeout); timeout = setTimeout(function(){executeAlarm(next)},next.time); } } function executeAlarm(next){ if(!next || !next.name) clearInterval(timeout) document.getElementById("alarms").innerHTML += "<span> Alarm for " + next.name + "</span>"; start(); } document.addEventListener( "DOMContentLoaded", start, false ); 
 <div id="alarms"></div> 

(代表OP发布)

问题出在这里,在机器人代码中:

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,帮助我找到正确的答案。

暂无
暂无

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

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