2

I have read this stackoverflow post several times How do I return the response from an asynchronous call?. For some reason, I just do not get it. Could someone post the example in the question here as an actual full working solution instead of the step by step guidance provided in section "2. Restructure Code" of the post which I am finding very confusing.

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- tried that one as well
        }
    });

    return result;
}

var result = foo(); // always ends up being `undefined`.
1
  • You need to work with the returned data in the callback.
    – Etheryte
    Commented May 13, 2015 at 20:40

3 Answers 3

8

The success function is a callback, meaning it can be called whenever. In this case, it is being called after the ajax call, and return result; is being called before the ajax call, meaning result is not assigned before returning it, which is why it's always undefined.

One way I like to fix this problem is by passing my own callback into the foo function then calling it when I receive the data, like this:

function foo(callback) {
    $.ajax({
        url: '...',
        success: function(response) {
            callback(response) // <-- call it here
        }
    });
}

foo(function(data){
    // use your data here
});
0
2

As it stands right now, you are returning result almost immediately from foo. The $.ajax() is called and the function immediately moves on to return result, which is undefined at that point; finally, when the ajax call is complete, you set result = response, but the function has long been complete (i.e., return result never happens again).

This is why asynchronous calls typically work with callbacks or promises. These are where you do your work after an asynchronous call completes. In your example, you could use promises, like:

function foo() {
    return $.ajax({
        url: '...'
    });
}

And then call it like:

var result;
foo().done(function(response) {
    result = response;
});

Or, you could do it with a callback, like:

function foo(callback) {
    return $.ajax({
        url: '...',
        success: callback
    });
}

And call that like:

var result;
foo(function(response) {
    result = response;
});
1

Since ajax requests are done asynchronously, the browser will continue executing code and will only come back to your callback (under success:) when the request is finished (and successful).

This means that if you have code that is dependent on the request's response, you'll have to encapsulate it inside your callback in order to make sure that it won't execute beforehand.

$.ajax({
    url : '...',
    success : foo
});

function foo(response) {
    console.log('This executes AFTER the request finished');
    // do your thing with the response
}

console.log('This executes BEFORE the request finished');

Not the answer you're looking for? Browse other questions tagged or ask your own question.