对于javascript爱好者,
如何编制setTimeOut
(或setInterval
)句柄,以便按分钟开始。因此,例如,如果它是当前时间的51秒,那么在9秒内触发它,如果是第14秒则在46秒内触发
感谢
答案 0 :(得分:17)
var date = new Date();
setTimeout(function() {
setInterval(myFunction, 60000);
myFunction();
}, (60 - date.getSeconds()) * 1000);
显然,这不是100%精确,但对于大多数情况来说应该足够了。
答案 1 :(得分:6)
var nextTick = function() {
return 60000 - (new Date().getTime() % 60000);
}, timerFunction = function() {
// do stuff
// do stuff
// do stuff
setTimeout(timerFunction, nextTick());
};
var timeout = setTimeout(timerFunction, nextTick());
答案 2 :(得分:1)
var seconds = (new Date()).getSeconds();
使用60-seconds
作为超时时间。当然,setTimeout
允许您指定毫秒,这意味着您还应该检查毫秒,但这将为您提供“足够接近”的大多数应用程序。如果有的话,这应该让你在几分之一秒内超过分钟,但最好是超调而不是下冲。使用这种方法,下冲会导致灾难性的失败。
答案 3 :(得分:1)
起初,我使用了Joel Potter提出的解决方案。在大多数情况下,他的解决方案足够好。但是,因为javascript一次只做一件事(除非你正在使用Workers),所以第一次超时可能会延迟,所以你的第一次超时会被执行,例如。 5秒太迟了,你会在每分钟后每隔5秒获得一次间隔。
所以,这是我的实现:
function setMyFunctionInterval()
{
var currentDateSeconds = new Date().getSeconds();
if (currentDateSeconds == 0) {
setInterval(myFunction, 60000);
}
else {
setTimeout(function () {
setMyFunctionInterval();
}, (60 - currentDateSeconds) * 1000);
}
myFunction();
}
setMyFunctionInterval();
答案 4 :(得分:1)
首先,让我们确定在下一分钟之前我们知道有多少时间:
var toExactMinute = 60000 - (new Date().getTime() % 60000);
现在,如果您想使用setTimeout
,那么
setTimeout(yourfunction, toExactMinute);
如果你想做setInterval
:
setTimeout(function() {
setInterval(yourFunction, 60000);
yourFunction();
}, toExactTime);
答案 5 :(得分:0)
var d = new Date();
var milisecondsUntilMinuteChanges = 60000 - d.getMilliseconds() - (1000 * d.getSeconds());
答案 6 :(得分:0)
function waitForNewMinute() {
if (new Date().getSeconds()>1) {
setTimeout(waitForNewMinute, 500);
} else {
setInterval(doMyThing,60000);
}
}
waitForNewMinute();
答案 7 :(得分:0)
虽然回复太迟了,但我最近有类似的问题要解决,并考虑分享我的方法。我的问题是在指定的秒数后根据远离一分钟的距离运行超时,然后每分钟运行间隔功能。这就是我所做的。
假设日期是使用date = new Date();
secondsLeft = 60 - date.getSeconds();
然后将超时功能设置为在 secondsLeft
之后运行,并在函数内部设置一个间隔函数,以便每分钟运行一次:
setTimeout(function() {
// perform the action **A**;
minuteMS = 60 * 1000; // seconds * milliSeconds
setIntervalId = setInterval(function() {
// perform the action **A**;
}, minuteMS);
}, secondsLeft);
答案 8 :(得分:0)
我使用了'((60-date.getSeconds())* 1000);'数据刷新功能上的方法,并且在工作时会随时间(在我更改它之前晚14秒)“漂移”。
由于数据需要在分钟内更新(并且显然没有发生,因为我们在同一页上有一个时钟!),这是我想出的解决方案:
setInterval(function () {
if(moment().format('ss') === "00"){
console.log('we are at the 0 - update the data!');
refresh_data();
}
}, 1000);
这当然是使用moment.js来找到“ 0”的时间,并且确实可以执行OP所要求的-在分钟内触发-每次!!
答案 9 :(得分:0)
我相信所有答案都是有缺陷的。启动setInterval后,如果不创建新的setInterval对象,则无法更改间隔时间。因此,您将只为每个迭代使用初始计算时间。 您可以创建新的setInterval对象,但这必须很昂贵。
请参阅:How do I reset the setInterval timer?
我的建议是创建一个使用setTimeout的循环函数。
以下是一些代码:
var duration = 5; //in minutes. This is just to control the total length
var startTime = new Date().getTime(); //must be in milliseconds
function myOnTheMinuteTimer(){
setTimeout(function(){
var currentTimeMS = new Date().getTime();
var diffMs = Math.abs(startTime - currentTimeMS);
diffMs = diffMs/1000; //take out the milliseconds
var seconds = Math.floor(diffMs % 60);
diffMs = diffMs/60;
var minutes = Math.floor(diffMs % 60);
var minutesLeft = duration - minutes;
console.log("Time passed:", minutes + "m :" + seconds + "s");
if(minutes <= duration){
console.log("Timer expired.");
} else {
myOnTheMinuteTimer();
}
}, setIntervalTimeToNextMinute());
}
//Initialize timer
myOnTheMinuteTimer();
//Get our time until the next minute
function setIntervalTimeToNextMinute(){
var currentDateSeconds = new Date().getSeconds();
if(currentDateSeconds == 0){
return 60000;
} else {
return (60 - currentDateSeconds) * 1000;
}
}
我的用例是会话超时:
startTime -允许我经过任何毫秒的时间。这样,我可以避免页面加载时出错。假设用户在特定时间登录。我捕获了该时间,然后将其传递给初始功能,它将重新调整为按分钟计算。
持续时间-我将持续时间检查用于超时设置。如果应用程序有20分钟的超时,那么我需要将用户路由到登录屏幕。
(可选)-您可以添加更多变体。假设您希望给用户2分钟的警告,他们将被注销。只需将有条件的else添加到条件中2分钟即可。
希望有帮助!编码愉快!
答案 10 :(得分:0)
这实际上可以通过将 setTimeout
与 setInterval
结合起来相当简单地完成。我将首先演示如何以长格式执行此操作,然后在下面提供一个速记单行函数,该函数将完成相同的操作。
function setEmomInterval(expr, ...rest) {
setTimeout(function() {
expr(...rest);
setInterval(expr, 60000, ...rest);
}, 60000 - new Date().getTime() % (60 * 1000));
}
setEmomInterval(() => console.log(`The time is now ${new Date().getHours()}:${new Date().getMinutes()}`));
这有一个额外的好处,它不仅可以精确到秒,而且实际上可以精确到毫秒,减去由于计算时间造成的任何最小延迟。
作为单线,它看起来像这样:
const setEmomInterval = (expr, ...rest) => setTimeout(() => (expr(...rest), setInterval(expr, 60000, ...rest)), 60000 - new Date().getTime() % (60 * 1000));
setEmomInterval(() => console.log(`The time is now ${new Date().getHours()}:${new Date().getMinutes()}`));
如前所述,由于计算时间中所谓的“漂移”,存在一些延迟。要解决此问题,如果您需要最准确的时间,请使用 Dan Kaplun 的 driftless 库(GitHub 上的 @dbkaplun)。