You seem to be confused as to how JS works:
a function makes an AJAX call and should not return until the AJAX results are returned. The trouble is, the AJAX function runs in a separate asynchronous thread
This statement contains a couple of fallacies:
- a function makes an AJAX call and should not return until the AJAX results are returned
- the AJAX function runs in a separate asynchronous thread
Both statements are completely untrue, and here's why:
A function that makes an ajax call does just that: it makes a call, it sends a request. AJAX stands for Asynchronous JavaScript And XML, a function that makes such a request, then, returns once the request is sent. What happens with the request, and how it is handled once a response is sent back is not the responsibility of the function that issued the request. Consider this:
function sendInfo(info)
{
var loader = $('#loader');
$.ajax({
url: 'your/url',
data: info,
type: 'post',
success: function(response)
{//this will get called when there is a response
loader.hide();//access to outer scope!
}
});
loader.show();
}
In this case, $.ajax
is the function that performs the request. If that were blocking, we wouldn't be able to show the loader. The function, though, returns after the request is sent, and the success
callback will be invoked once there is a response to handle. That function will take care of the loader, ie hide it again. If AJAX calls were blocking, we wouldn't have responsive and dynamic sites like pretty much all sites are today (autocomplete google searches, or even this site...)
AJAX functions run in a separate thread is just not true. AJAX is a type of request, the functions you're referring to are either the functions that issue the request, which don't run in a separate thread, or the callbacks/handles. These also don't run in a separate thread.
JavaScript is, and has always been, single threaded. It does have an event loop. On each event, JS checks if there are listeners bound to handle the event. If not, that's an end of it, if there are, these handlers will be invoked one at a time. While these handlers are being invoked, not other code can be executed.
Now to answer your question: how do we return from these functions? Well, in a way, you already are: all functions return something. But I take it you want to know how you can assign the return value of these functions to a variable. The simple answer is: you can't. Not directly at least:
//not using jQuery:
var returnVal = xhr.send();
Will not return the value of the success (onreadystatechange
) handler, simply because the onreadystatechange
event will occur 4 times! What you can do is use closure variables, module pattern or, if you must, globals.
If these functions were to run in separate threads, scope and accessing global variables would leave you with a lot of concurrency issues, and manipulating the DOM would be right out. Instead, you can do this:
var infoModule = (function()
{
var loader = $('#loader'),
module = {response: undefined};
module.sendInfo = function(info)
{
$.ajax({
url: 'your/url',
data: info,
type: 'post',
success: function(response)
{//this will get called when there is a response
loader.hide();//access to outer scope!
module.response = response;
}
});
loader.show();
};
return module;
}());
Now you can do something like this:
infoModule.sendInfo({data: 'foo'});
and after the request is completed, you can get at the response of the call like so:
infoModule.response;