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 JSO开发者_JS百科NP), 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?
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){
});
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) {
});
精彩评论