it would work better using async ajax, sync tend to freeze browser ui, sometimes even on different tabs!
the problem you describe is a good candidate for an event-driven core.
in javascript, that means callbacks.
if you find your code nesting callbacks in such a way that indentations work the code further and further to the right, abandon that code. Not only is it hard to get going, it's a nightmare to maintain.
you will need:
- a central collection of data, events, and status.
- a reusable ajax function with a callback.
since i have no idea what you're trying to do, let's pretend you are displaying the weather for someplace. what place? let's assume the user's geolocation, as provided by window.navigator. it's provided by a callback as well, so it's a good fit. problem is, it gives me lat/lon coords, and my weather API expects zip codes. I need to turn the lat/lon into a zip code, and then query the weather API using that zip.
Code:
Weather={
init: function weather_init(strDivIdForForcastHTML){
this.div=window[strDivIdForForcastHTML];
this.stat("Determining Location...");
navigator.geolocation.getCurrentPosition(this.incomingGeo);
},
incomingGeo: function _glcb(e){
this.stat("Looking Up Zip...");
addScript(
geo2zipURL+
"?lon="+e.coords.longitude+
"&lat="+e.coords.latitude +
"&cb=Weather.incomingZip"
);
} ,
incomingZip: function _zpcb(e){
this.stat("Fetching forecast...");
this.zip=e.postal;
addScript(
weathByZipURL+
"?zip="+e.postal +
"&callback=Weather.incomingForecast"
);
},
incomingForecast: function _fccb(e){
this.stat( "weather for "+this.zip+" : "+ e.results.forecast.html);
},
stat: function _stat(strStatus){
this.div.innerHTML=strStatus;
}
}//end Weather object
//usage:
Weather.init("weatherPanel");
note how the dependencies don't nest; events modify
this/Weather to store and share data.
while this is a simple demo, the distinction makes a HUGE difference on complex apps.
your problem sounds like it needs 3 callbacks:
-all tasks done
-main task done
-sub task done
if the main task checks to see if the sub tasks are done and calls the next sub-task or main-task IF needed, it can be repeatedly called, from the sub-task callback, until all the sub tasks are done.
another option is to have the subtask callback trigger a counter or amend a LIFO stack and re-dispatch "almost itself" if needed. again, use this.something so that all the callback are seeing/setting the same data.
using nested callbacks can create impossible-to-reach closures, which hide incoming data and make debugging more painful.
save more info than you need at each step, it might be useful later, and doesn't cost much to code or run.