7

I am trying to "cache" some information by storing it in a variable.
If 2 minutes have passed I want to get the "live" values (call the url). If 2 minutes have not passed I want to get the data from the variable.

What I basicly want is:

if(time passed is less than 2 minutes) {
    get from variable
} else {
    get from url
    set the time (for checking if 2 minutes have passed)
}

I've tried calculating the time with things like

if((currentime + 2) < futuretime)

but it wouldn't work for me. Anybody know how to properly check if 2 minutes have passed since the last executing of the code?

TL;DR: Want to check if 2 minutes have passed with an IF statement.

tkone
  • 22,092
  • 5
  • 54
  • 78
Parrotmaster
  • 647
  • 1
  • 7
  • 27
  • I think you might be approaching this from the wrong angle. You can declare a variable which can have it's value updated every 2 minutes. Then it doesn't matter when you access it, it will either return the existing value or if a n+2 minute threshold has passed then it will return the new value. – andyb Mar 07 '13 at 15:08

5 Answers5

12

Turning your algorithm into working javascript, you could do something like this:

var lastTime = 0;

if ( Math.floor((new Date() - lastTime)/60000) < 2 ) {
    // get from variable
} else {
    // get from url
    lastTime =  new Date();
}

You could put the if block in a function, and call it anytime you want to get the info from either the variable or the url:

var lastTime = 0;

function getInfo() {
    if ( Math.floor((new Date() - lastTime)/60000) < 2 ) {
            // get from variable
    } else {
        // get from url
        lastTime =  new Date();
    }
}

Hope it helps.

rdleal
  • 987
  • 5
  • 15
  • Thanks, but this always calls the IF and not the ELSE after 2 minutes. – Parrotmaster Mar 07 '13 at 14:34
  • Sorry, my bad. the `lastTime` variable should initially be `0`. Answer edited. – rdleal Mar 07 '13 at 14:35
  • It works almost exactly as I wanted. The first time it calls the "live" URL and after that only calls the Cache. However after 2 minutes (or 1 for testing purposes) it doesn't call the url. Also in the ELSE is where it calls the live the first time and in the IF is where it calls the variable, exactly opposite of your example (but switching the code fixed it). – Parrotmaster Mar 08 '13 at 10:09
  • Nevermind my earlier comment. IT WORKS! Thank you so much this is exactly what I wanted :D – Parrotmaster Mar 08 '13 at 10:15
4

If you want to do something on a timer in JavaScript, you should be using setTimeout or setInterval.

Having your code run in a continuous loop will cause your browser's VM to crash.

Using setTimeout is rather easy:

setTimeout(function(){
    // do everything you want to do
}, 1000*60*2);

This will cause the function to run in at least two minutes from the time the timeout is set(see this blog post from John Resig for more deatils). The second argument is the number of milliseconds, so we multiply by 60 to get minutes, and then 2 to get 2 minutes.

setInterval, which follows the same syntax will do something EVERY x milliseconds.

Community
  • 1
  • 1
tkone
  • 22,092
  • 5
  • 54
  • 78
  • I don't want my code to do something every 2 minutes. I want my code to execute a specific code if 2 minutes have passed, if not it will do something else. To clarify, it will only perform the IF statement after a user has refreshed the page. The code will then check if 2 minutes have passed since last call. – Parrotmaster Mar 07 '13 at 13:55
  • @Parrotmaster How are you going to check to see if 2 minutes have passed? Is this in reaction to the user providing some input? Like if they click on this box AND two minutes have passed, do x, otherwise do y? – tkone Mar 07 '13 at 13:58
  • Exactly, I want the code to get content from an URL if 2 minutes have passed, otherwise get content from the variable. – Parrotmaster Mar 07 '13 at 14:00
  • 1
    @Parrotmaster ah. there are better answers in this question than this. – tkone Mar 07 '13 at 17:16
1

Without using 3rd party libs, just use Date.getTime() and store it as some variable:

var lastRun = null;

function oneIn2Min() {
    if (lastRun == null || new Date().getTime() - lastRun > 2000) {
        console.log('executed');
    }
    lastRun = new Date().getTime();
}

oneIn2Min();  // prints 'executed'
oneIn2Min();  // does nothing
oneIn2Min();  // does nothing
setTimeout(oneIn2Min, 2500);  // prints 'executed'

You can also opt to make some simple object out of it (to keep your code organised). It could look like this:

var CachedCall = function (minTime, cbk) {
    this.cbk = cbk;
    this.minTime = minTime;
};

CachedCall.prototype = {
    lastRun: null,

    invoke: function () {
        if (this.lastRun == null || new Date().getTime() - this.lastRun > this.minTime) {
            this.cbk();
        }
        this.lastRun = new Date().getTime();
    }
};

// CachedCall which will invoke function if last invocation
// was at least 2000 msec ago 
var c = new CachedCall(2000, function () {
    console.log('executed');
});

c.invoke(); // prints 'executed'
c.invoke(); // prints nothing
c.invoke(); // prints nothing 
setTimeout(function () {c.invoke();}, 2300); // prints 'executed'
kamituel
  • 34,606
  • 6
  • 81
  • 98
  • I tried the first option but it always gives me the result of the IF and not the ELSE after calling the IF the first time. The code I'm running is already inside a function that's generating the entire page. – Parrotmaster Mar 07 '13 at 14:17
  • I'm not sure what you mean. My code works as follows: Each call to oneIn2Min() prints 'executed' unless oneIn2Min() was called less then 2 seconds ago. Is this the expected behaviour? – kamituel Mar 07 '13 at 14:20
  • I'm not putting it into a function because then I'd have to call the function right after it's made, so I might aswell just execute it instantly. – Parrotmaster Mar 07 '13 at 14:22
  • The whole point is to declare function once, and then call it multiple times. – kamituel Mar 07 '13 at 14:25
  • Ok, in that case I will keep looking. Thanks anyways. – Parrotmaster Mar 07 '13 at 14:26
  • Check this out: http://jsfiddle.net/bEPDp/1/ Here this code works as expected (you can see logs in javascript console) – kamituel Mar 07 '13 at 14:37
  • I've now tried it by calling the function with an IF statement but it always returns true (set IF to return true and ELSE to return false). – Parrotmaster Mar 08 '13 at 09:25
  • I would really need to see more of the code you're executing, because I think I just don't get what you're trying to do. – kamituel Mar 08 '13 at 09:49
0

If you're open to include 3rd party libs this might be very handy in other tasks too: http://momentjs.com/docs/#/manipulating/add/

Ramunas
  • 3,853
  • 1
  • 30
  • 31
  • Preferably not, the website must be as lightweight as I can possible make it, otherwise I would have used PHP for this specific function. – Parrotmaster Mar 07 '13 at 13:50
0

You can do something like that

var myVal = {
  data: null,
  time: new Date()
}

function getMyVal () {
  if(myVal.time < new Date(new Date().getTime() - minutes*1000*60)) {
    myVal.data = valFromRequest;
    myVal=time=new Date();
  }
  return myVal.data;
}
Thomas Durieux
  • 466
  • 2
  • 5