JavaScript:如何每隔一小时做某事?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12309019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript: How to do something every full hour?
提问by matlos
I want to execute some JS code every hour. But I can't use
我想每小时执行一些 JS 代码。但是我不能用
setInterval("javascript function",60*60*1000);
because I want to do it every full hour, I mean in 1:00, in 2:00, in 3:00 and so on. I am thinking about something like
因为我想每个小时都做一次,我的意思是在 1:00、2:00、3:00 等等。我正在考虑类似的事情
var d;
while(true) {
d = new Date();
if ((d.getMinutes() == '00') && (d.getSeconds() == '00')){
// my code here
}
}
but it's too slow and it doesn't work well.
但它太慢了,而且效果不佳。
Thak you for any ideas
谢谢你的任何想法
回答by Heretic Monkey
I would find out what time it is now, figure out how long it is until the next full hour, then wait that long. So,
我会找出现在几点,弄清楚距离下一个完整小时还有多久,然后等那么久。所以,
function doSomething() {
var d = new Date(),
h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() + 1, 0, 0, 0),
e = h - d;
if (e > 100) { // some arbitrary time period
window.setTimeout(doSomething, e);
}
// your code
}
The check for e < 100
is just to make sure you don't do setTimeout
on something like 5 ms and get it a crazy loop.
检查e < 100
只是为了确保您不会setTimeout
在 5 毫秒之类的事情上进行操作并使其陷入疯狂循环。
回答by Niet the Dark Absol
What you can do is have an interval run every minute, and check if the time is :00
before running the actual code.
您可以做的是每分钟运行一次间隔,并检查时间是否:00
在运行实际代码之前。
回答by Rami Jarrar
look at this one :
看看这个:
function to_be_executed(){
...
...
...
makeInterval();
}
function makeInterval(){
var d = new Date();
var min = d.getMinutes();
var sec = d.getSeconds();
if((min == '00') && (sec == '00'))
to_be_executed();
else
setTimeout(to_be_executed,(60*(60-min)+(60-sec))*1000);
}
回答by Ethan Brown
You could do it by clearing and setting the interval each time. It's just that first time, instead of the interval being one hour, it would be one hour minus the current minutes and seconds:
您可以通过每次清除和设置间隔来实现。这只是第一次,而不是一小时的时间间隔,而是一小时减去当前的分钟和秒:
var d = new Date();
var secondsPastHour = d.getMinutes()*60 + d.getSeconds();
var intervalId = setInterval( myFn, 60*60*1000 - secondsPastHour*1000 );
function myFn() {
// do stuff
// ...
clearInterval( intervalId );
intervalId = setInterval( myFn, 60*60*1000 );
}
The only problem with this is that eventually it will probably start drifting...the solution to that would be to just do the same thing inside the function as you do when kicking it off:
唯一的问题是它最终可能会开始漂移……解决这个问题的方法是在函数内部做同样的事情,就像你在启动它时所做的一样:
var d = new Date();
var secondsPastHour = d.getMinutes()*60 + d.getSeconds();
var intervalId = setInterval( myFn, 60*60*1000 - secondsPastHour*1000 );
function myFn() {
// do stuff
// ...
clearInterval( intervalId );
var d = new Date();
var secondsPastHour = d.getMinutes()*60 + d.getSeconds();
intervalId = setInterval( myFn, 60*60*1000 - secondsPastHour*1000 );
}
Here's a proof of concept that updates every minute (I didn't want to wait a whole hour to test my code!): http://jsfiddle.net/dRsua/
这是每分钟更新一次的概念证明(我不想等待一个小时来测试我的代码!):http: //jsfiddle.net/dRsua/
回答by Luc Bocahut
This is how I would go about it, expanding on the previous answer:
这就是我将如何去做,扩展了之前的答案:
function callEveryFullHour(my_function) {
var now = new Date();
var nextHour = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours() + 1, 0, 0, 0);
var difference = nextHour - now;
return window.setTimeout(function(){
// run it
my_function();
// schedule next run
callEveryFullHour(my_function);
}, difference);
}
This way you can start stop any function from running on the full hour.
通过这种方式,您可以开始停止任何功能在整小时内运行。
Usage:
用法:
let my_function = () => { // do something };
let timeout = callEveryHour(my_function);
// my_function will trigger every hour
window.clearTimeout(timeout);
// my_function will no longer trigger on the hour
回答by Steffan
ES6 version, works in NodeJS and modern browsers - executes on millisecond according to browser or server clock.
ES6 版本,适用于 NodeJS 和现代浏览器 - 根据浏览器或服务器时钟以毫秒为单位执行。
Function:
功能:
const doSomething = (something) => {
let running = true
let nextHour = () => {
return 3600000 - new Date().getTime() % 3600000
}
let nextCall = setTimeout(() => {
something()
doSomething(something)
}, nextHour())
return {
next() { return running ? nextHour() : -1 },
exec() { something() },
stop() {
clearTimeout(nextCall)
running = false
},
start() {
clearTimeout(nextCall)
nextCall = setTimeout(() => {
something()
doSomething(something)
}, nextHour())
running = true
}
}
}
Usage:
用法:
// Do something at next full hour and repeat forever
doSomething(() => console.log('Full hour reached!'))
// Do something every full hour & stop it
let obj = doSomething(() => console.log('Will I ever execute? :/'))
obj.next() // Time to next execution in milliseconds
obj.next() / 1000 // Time to next execution in seconds
obj.next() / 1000 / 60 // Time to next execution in minutes
obj.stop() // Stop executing every full hour
obj.start() // Continue executing every hour
obj.exec() // Execute now
回答by RedSparr0w
You could use something like the function below, which is very easy to adapt to your needs.
您可以使用类似下面的函数,它很容易适应您的需求。
It calculates how long until the next interval, and will then re-run the script after it has been run each time (unless you set the 3rd argument to true).
它计算下一次间隔的时间,然后在每次运行后重新运行脚本(除非您将第三个参数设置为 true)。
function runOnInterval(interval_in_ms, function_to_run, only_run_once = false){
setTimeout(()=>{
function_to_run();
if (!only_run_once) runOnInterval(...arguments);
}, interval_in_ms - ((Date.now() - (new Date().getTimezoneOffset() * 6e4)) % interval_in_ms));
}
Example Usage:
示例用法:
// Every day at midnight:
runOnInterval(24 * 60 * 60 * 1000, my_function_to_run);
// Every hour on the hour:
runOnInterval(60 * 60 * 1000, my_function_to_run);
// Every minute on the minute:
runOnInterval(60000, my_function_to_run);
// Every 10 seconds on the 10 second mark:
runOnInterval(1e4, ()=>console.log('this will be run every 10 seconds on the 10 second mark'));
回答by Strille
One simple way would be to continously run a check to detect when the hour changes:
一种简单的方法是不断运行检查以检测小时何时更改:
var lastProcessedHour = -1;
setInterval(function() {
var d = new Date();
var currentHour = d.getHours();
if (currentHour != lastProcessedHour) {
// do stuff
console.log("new hour");
lastProcessedHour = currentHour;
}
}, 1000);
If you run it every second like above the script will trigger one second into the new hour at the latest.
如果你像上面一样每秒钟运行一次,脚本将最迟触发一秒进入新的一小时。
I think this method is both robust and easy to understand, and from a performance standpoint it should't really be an issue to run this simple check once every second.
我认为这种方法既健壮又易于理解,从性能的角度来看,每秒运行一次这个简单的检查应该不是问题。
回答by raphadko
Was also looking for this, based on Mark's response, I wrotethis:
也在寻找这个,基于马克的回应,我写了这个:
function callEveryFullHour() {
var now = new Date();
var nextHour = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours() + 1, 0, 0, 0);
var difference = nextHour - now;
window.setTimeout(function(){
// code goes here
console.log("It's a full hour!")
callEveryFullHour();
}, difference);
}
回答by Michal
You need to run a setInterval function every minute (or every second depending on how accurate you want your timer to be) and execute your code when minutes are zero (btw get minutes returns a number between 0 and 59)..
您需要每分钟运行一次 setInterval 函数(或每秒运行一次,具体取决于您希望计时器的准确程度)并在分钟为零时执行您的代码(顺便说一下 get minutes 返回一个介于 0 和 59 之间的数字)。
function myTimer() {
var d = new Date()
if (d.getMinutes() == 0) {
console.log("full hour");
}
}
timer = setInterval(function(){myTimer()},60000)
If you do not want to have an interval running every second/minute after you established that you are on full hour you can simply trigger a new hourly interval and clear the initial one.
如果您不想在确定您处于完整小时后每隔一秒/分钟运行一次间隔,您可以简单地触发一个新的每小时间隔并清除初始间隔。
var myHourlyTimer = null;
function myTimer() {
var d = new Date()
if (d.getMinutes() == 0) {
console.log("full hour");
myHourlyTimer = setInterval(function(){myHourlyTimerFunction()},3600000);
clearInterval(timer)
}
}
timer = setInterval(function(){myTimer()},60000)