Azanyr
Azanyr

Reputation: 197

Nested Ajax Requests – Order of Execution Issue

I have 2 nested AJAX requests in my code. They are fired when a button is pressed. I'm using Bootstrap's loading stages to change the button's text to "Loading…" while the AJAX requests are being processed.

The issue is that the button gets reset before the inner AJAX request has completed.

My expectation is that the complete callback of the outer AJAX request would be executed only after all the code in its success callback has been executed, but that's not what's happening.

The code's simplified version looks like this:

$('#button').on('click', function() {
$.ajax({
    url: …,
    type: 'post',
    data: …,
    dataType: 'json',
    beforeSend: function() {
        $('#button').button('loading');
    },
    complete: function() {
        $('#button').button('reset');
    },
    success: function(json) {
        if (json['error']) {
        …
        } else {
            $.ajax({
                url: …,
                dataType: 'json',
                success: function(json) {
                    for (var delayer = 1; delayer < 2000000000; delayer++) {}
                    …
                },
                error: …
            });
        }
    },
    error: …
});             
});

I've created the arbitrary delaying loop to be able to better test the effect on my machine. It gives me about 2 seconds of delay. The button resets almost instantly though.

Is that how it's supposed to work and if it's not – how can I fix it?

Upvotes: 0

Views: 311

Answers (1)

robere2
robere2

Reputation: 1716

the complete function in your first AJAX request is being fired when your first AJAX request is completed. If you want it to be fired after the second one is completed, just move it into the second AJAX request. :)

$('#button').on('click', function() {
$.ajax({
    url: …,
    type: 'post',
    data: …,
    dataType: 'json',
    beforeSend: function() {
        $('#button').button('loading');
    },
    success: function(json) {
        if (json['error']) {
        …
        } else {
            $.ajax({
                url: …,
                dataType: 'json',
                complete: function() {
                    $('#button').button('reset');
                },
                success: function(json) {
                    for (var delayer = 1; delayer < 2000000000; delayer++) {}
                    …
                },
                error: …
            });
        }
    },
    error: …
});             
});

The reason you are confused is because the complete callback is fired at the same time the success callback is fired (approximately). The only difference is complete is fired no matter what the result, while success is only fired when it gets a positive response (i.e. HTTP 200 OK)

complete IS NOT fired when success is complete. For more info check out the jQuery documentation

The documentation does say that the complete is fired after success execution, but this is does not mean that all of success finishes before complete is even called. This has to do with asynchronous coding in JavaScript.

Upvotes: 1

Related Questions