Lelio Faieta
Lelio Faieta

Reputation: 6684

set timeout for the first execution

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

Answers (6)

The Guest
The Guest

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

Hurricane Hamilton
Hurricane Hamilton

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

lyjackal
lyjackal

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

Leonardo Moreno
Leonardo Moreno

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

Aleuck
Aleuck

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

Kiran Reddy
Kiran Reddy

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

Related Questions