Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing cache synchronously in js

I'm maintaining a cache in JavaScript using jquery in a global cache variable.

Whenever new information is received using AJAX it is added to the cache.

If it is not in the cache, I want to AJAX it from the server.

I want to implement a function to query on demand and to use it like so:

$("#label").html(GetName("user123"));

Where GetName() should be like:

function GetName(username) {
    if (Cache[username] != null) return Cache[username];
  else
    return QueryUsernameFromServer(username)
}

QueryUsernameFromServer() should be like:

function QueryUsernameFromServer (username) {
    return $.ajax(…);
}

However, $.ajax is async meaning that it cannot wait for a value (and thus cannot return it).

Using $.ajax in sync mode is highly not recommended (browser hangs and it doesn’t support JSONP), http://api.jquery.com/jQuery.ajax/

Using this, http://www.techfounder.net/2008/05/17/simple-javascript-cache/, approach requires a callback. However, creating a callback for each use is not desired.

Is there a good way to implement a “cache on demand” function in js and ajax without a dedicated callback for each use?

like image 795
user759463 Avatar asked May 18 '11 15:05

user759463


2 Answers

You'll need to have the callback, because AJAX is...wait for it..."A"synchronous.

Just add a callback to your functions that query the cache. It's pretty simple:

function getName(username, callback){
  if(cache[username]){ 
     // cache hit, immediately invoke the callback
     callback(cache[username]); 
  }else{ 
    // assumes this query function updates the cache and invokes the
    // 2nd parameter when it completes
    queryUsernameFromServer(username, function(){
      // invoke the callback now
      callback(cache[username]);
    }); 
  }
}

And simply convert to an async style in your code:

Before:

var name = getName('jvenema');

After:

getName('jvenema', function(name){

});
like image 76
jvenema Avatar answered Oct 04 '22 21:10

jvenema


If your using jQuery 1.5+ then you can just use deferreds.

function GetName(username) {
    if (Cache[username] != null) return $.when(Cache[username]);
  else
    return QueryUsernameFromServer(username)
}

And use deferreds as follows

GetName('jvenema').done(function(name) {

});
like image 27
Raynos Avatar answered Oct 04 '22 23:10

Raynos