How can I modify the callAjax function to use async mode and leave the master scripts (hundreds or thousands of them) un-changed ?
You can't. If you use asynchronous ajax, then you can't return the value from the function because the function will return BEFORE the value is available. You simply can't make an async operation into a synchronous function. For a lot more detail on returning asynchronous operations from a function, see How do I return the response from an asynchronous call?. You will see that all the available options involve calling a callback when the async value is done or returning a promise and using a callback with .then()
on the promise to know when the value is done and what it is.
If your requirement is that you block the UI and that you can't change the calling code, then you have to stick with synchronous Javascript. No asynchronous operation will do either.
Otherwise, get rid of those requirements and write proper asynchronous calling code and don't block the UI in this way (you can protect the contents of the screen from editing or button presses during the ajax operation with different techniques).
So, my conclusion from the problem you've described is that you need to lift some of your current requirements because there is no solution that:
- Blocks the UI
- Uses only asynchronous Ajax
- Returns the ajax obtained value directly from
callAjax()
- Does not change the calling code that calls
callAjax()
You can't do all of those at once.
The forward moving design choice would be to return a promise from callAjax()
and fix all the calling code that uses it to use that promise. For blocking the UI, you'd have to use some sort of UI protection (screen veil, you called it, or something like that).
My advice if you have a large body of code using this old synchronous ajax function is to create a new ajax function with a different name that returns a promise and deprecate use of the old one for any new code (make all new code use the new one). Then, as needed and guided by business goals, rewrite uses of the old function to use the new one one at a time. This will at least stop more code being written with the old, synchronous ajax code. And, it will give you an opportunity over time to convert code to the new interface as needed.
Note that the closest thing you could get to calling code that looks close to what you have (but still requires changes) would be using async/await
(available in the ES7 specification or in transpilers). You'd return a promise from callAjax()
and then, the caller can await
the result:
// async function returns a promise
async function someFunction() {
try {
// some code filling parameter1
var response1 = await callAjax2(parameter1);
// some code using response1 and filling parameter2
var response2 = await callAjax2(parameter2);
// etc...
} catch(e) {
// handle error here
}
}
P.S. It looks like your current code doesn't have a good way to communicate back ajax errors.