I have a function which takes a parameter and does synchronous loadings.
I changed it to do an asynchronous jQuery.ajax call to retrieve data and call a callback. Old code (which cannot be modified) uses the same function and fails. I need to be able to retrieve the data both ways so async code can keep on running and old sync code can retrieve the cached data if async already loaded it, load it synchronously or wait for any async requests which are already running.
var ajaxQueries = {}
loadEngineData(fileId, callback) {
var sync = callback == undefined;
if (ajaxQueries[fileId]) {
if (sync) {
//Need to stop here and wait for ajaxQueries[fileId] to finish
//Execution cannot continue! If we return before defered has ended here 3rd party scripts will fail.
return data;
}
else {
ajaxQueries[fileId].done(function(data){callback(data)});
}
}
else {
ajaxQueries[fileId] = $.ajax({
async:!sync,
type:'GET',
url:fileId2Name(fileId),
data:null,
dataType:'text',
});
if (sync) {
var _data = undefined;
ajaxQueries[fileId].done(function(data){_data=data});
return _data;
}
ajaxQueries[fileId].done(function(data){callback(data);});
}
}
If an old script calls the function the ajax query will run synchronously and all subsequent calls will use the deferred .done
and .fail
and everything will be fine.
var enginePhyData = loadEngineData('physics');
//Do stuff
If a new script calls the function first and during this loading an old script tries to load data from the same file, I end with a situation where the deferred ajax query in ajaxQueries[fileId]
is running asynchronously and I have to wait for it to finish loading the data to avoid breaking the existing libs.
I simplified loadEngineData
to keep the question focussed. Otherwise it's a bit more complex and allows calling a list of files to load in parallel
loadEngineData(['geometry', 'scripts'], function() {
var phy = loadEngineData('physics');
var geo = loadEngineData('geometry');
var scr = loadEngineData('scripts');
//run the async function;
});
loadEngineData('physics', function() {
//run the async function;
});
//...
//in the scripts file
var phy = loadEngineData('physics');
//here phy might be undefined if this file went through eval() before `loadEngineData('physics',...)` was called;
I could modernize the code, but the issue is that some files are shared across projects and run in different environments. I can't currently modify the old scripts without forking the dependencies.
You cannot stop the execution of javascript while waiting for some asynchronous ajax call to finish. Javascript simply doesn't work that way.
Instead, you have to rework the way you program so that code that wants to wait for an asychronous ajax call to be completed will execute via a callback function, not synchronously after the ajax call executes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With