0

Is it a requirement to expressly return from a JavaScript function? In other languages, we tend to get a stack overflow error when functions don't return, but this does not seem to be the case with JavaScript.

Also, being asynchronous, it's sometimes difficult to determine when a function returns. They return even before an AJAX call or jQuery animation completes.

For example, 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. How would we return from such a function?

iSofia
  • 1,412
  • 2
  • 19
  • 36

2 Answers2

1

It is not a requirement to expressly return from a JavaScript function.

The trouble is, the AJAX function runs in a separate asynchronous thread. How would we return from such a function?

All JavaScript functions will return at the end of their scope. If no return statement is defined, a function will return undefined. The AJAX call will return to the callback and and cause the readystatechange event once it is completed.

See: Does every Javascript function have to return a value?

Community
  • 1
  • 1
LazerSharks
  • 3,089
  • 4
  • 42
  • 67
  • Thank you for your answer, Gnuey. 1.So, no risk of overflows? 2.Where would the AJAX response function return to? The function that spawned it returned as soon as the AJAX call was made. – iSofia Nov 28 '14 at 03:45
  • No risk of overflows, as far as I know. I don't know much about browser interpreters and such. Like you stated, one can write functions that make an AJAX call and WAITS until the AJAX call returns. This function is called a "callback function". The AJAX call will return results to this callback function. Read more here: http://stackoverflow.com/questions/3523628/newbie-approach-what-is-a-javascript-callback-function – LazerSharks Nov 28 '14 at 03:56
  • 1
    An ajax function _does not_ run in a separate thread. JS is single threaded. The callback will be invoked once the `readystatechange` event fires. At which point, the function call is put in the call queue, to be invoked ASAP. But the function itself is invoked in the same thread as the rest of the code, and is therefore blocking. write a callback/handler that takes seconds to return, and you'll notice that it blocks the UI. If the callback were to run in a separate thread, it wouldn't have safe access to higher scopes, and accessing the DOM would be risky, if not impossible – Elias Van Ootegem Nov 28 '14 at 14:55
1

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:

  1. a function makes an AJAX call and should not return until the AJAX results are returned
  2. 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;
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149