I am trying to provide a dictionary of status values to an application implemented in JS/jQuery. The values have to be fetched from a server (ajax). I want to do that in an asynchronous way, so that I can start that request during initialization. The actual access to the values should be done synchonously later to keep the code easy to understand. The (much) simplified code currently looks like this:
Initialization:
$(document).ready(function(){
Status.fetch();
})
Structure:
Status:{
Valid:new $.Deferred(),
Server:{},
/* ... */
fetch:function(){
if (Status.Valid.isResolved()){
// status already present due to a past request
return Status.Valid.promise();
}else{
// fetch status information from server
$.ajax({
type: 'GET',
url: 'status.php'),
cache: true,
dataType: 'json'
}).done(function(response){
$.each(response,function(key,val){
Status.Server[key]=val;
});
Status.Valid.resolve(Status.Server);
}).fail(function(response){
Status.Valid.reject(NaN);
});
return Status.Valid.promise();
}
}, // Status.fetch
getServerAspect:function(aspect){
$.when(
Status.fetch()
).done(function(server){
return server[aspect];
}).fail(function(server){
return NaN;
})
/* whyever: processing always comes here, which I don't understand... */
}, // Status.getServerAspect
} // Status
Status.Server
gets filled by the ajax call (which works). Status.getServerAspect()
is an example for a method to allow synchronous access to the aspects stored inside the Status.Server
structure (which does not work).
The basic idea is that the asynchonous filling of the structure runs before the structure is accessed. Every (synchronous) access is meant to either returned the referred aspect right away or block until that value is present. But whatever style I try inside Status.getServerAspect()
, the method returns right away without any aspect value I can use in the calling scope.
I obviously have a problem to understand the basic concept of working with deferred objects. I use them for synchronous processing all the time, works like charm. But that means that you have to use asynchronous style throughout your appliciation. For this special feature I prefer an synchronous style, so that conditional expressions stay simple:
if ('somevalue'==Status.getServerAspect('someaspect'))
...do something...
What is the trick to build a 'bridge' between asynchronous and synchronous handling?