Reputation: 6684
I use this script to retrieve new contents for a page each hour.
(function worker() {
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
},
complete: function() {
setTimeout(worker, 3600000);
}
});
})();
It loads the content every 60 minutes but what I really whant is to load the new contents at the beginning of each hour (i.e. at 8:00 and then again at 9:00). If I first load the page at the beginning of an hour my code is usefull but if I first load it during an hour (for example at 7:45) it reload contents at 8:45 and so on. How can I improve my code to say that the first time the reload should happen after 15 minutes and then at each hour? How do I change setTimeout function to achieve my goal? I have found a piece of code that can be close to my goal but I'm stucking my head on how to integrate it in my function:
function refreshAt(hours, minutes, seconds) {
var now = new Date();
var then = new Date();
if(now.getHours() > hours ||
(now.getHours() == hours && now.getMinutes() > minutes) ||
now.getHours() == hours && now.getMinutes() == minutes &&
now.getSeconds() >= seconds) {
then.setDate(now.getDate() + 1);
}
then.setHours(hours);
then.setMinutes(minutes);
then.setSeconds(seconds);
var timeout = (then.getTime() - now.getTime());
setTimeout(function() { window.location.reload(true); }, timeout);
}
Upvotes: 0
Views: 341
Reputation: 708
in javascript you will get current time's minutes by:
var date = new Date();
var minutes = date.getMinutes();
Now in your code, try something like:
if(minutes == 0){
setTimeout(worker, 3600000);
}else{
setTimeout(worker, 3600000-minutes*1000);
}
But make sure you get your contents for the first time, if minutes == 0.
Upvotes: 0
Reputation: 574
Instead of messing with Date objects directly, I would use this library: http://momentjs.com/docs/
You then have something simple like this, which avoids writing custom date logic, and is easy to read:
var worker = function() {
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
},
complete: function() {
setTimeout(worker, moment().endOf('hour').valueOf());
}
});
};
setTimeout(worker, moment().endOf('hour').valueOf());
Upvotes: 0
Reputation: 3984
You can just calculate the remaining milliseconds till the next hour
function doNextHour(callback) {
// time now in milliseconds since 1970
var now = new Date().getTime();
var MS_IN_HOUR = 60 * 60 * 1000;
// remaining ms until next hour
var remaining = MS_IN_HOUR - (now % MS_IN_HOUR);
setTimeout(callback, remaining);
}
Use like
(function worker() {
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
},
complete: function() {
doNextHour(worker);
}
});
})();
Make sure you also call the worker()
initially to start the cron job
Upvotes: 1
Reputation: 172
What about recalculating the delay every loop:
(function worker() {
var next_call = 60 - new Date().getMinutes();
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
},
complete: function() {
setTimeout(worker, next_call*60*1000);
}
});
})();
Upvotes: 0
Reputation: 294
Make the first timeout with the offset for the hour.
setTimeout(worker,3600000 - ((new Date) % 3600000))
This will be somewhat accurate (Date object construction might take some milliseconds).
Upvotes: 0
Reputation: 556
This could work for you
function worker() {
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
},
complete: function() {
setTimeout(worker, 3600000);
}
});
}
var mins = new Date().getMinutes();
if(mins > 0){
mins = 60 - mins;
}
setTimeout(worker, mins*60*1000);
Upvotes: 0