Rodrigo Ruiz
Rodrigo Ruiz

Reputation: 4355

jQuery- are ajax responses received in order?

If I have something like:

var result;

var searchFunction = function(query) {
    $.ajax({
        url: '..',
        type: 'GET',
        data: {
            'query': query
        },
        success: function(result) {
            r = result
        }
    });
};

will r always end up to be the result from the last searchFunction(query) call?

For example, lets say I do this:

searchFunction('query1'); // this one takes 3 seconds to return because of internet delay
searchFunction('query2'); // this one takes 1 seconds to return because of less internet delay

will my r be 'result1' or 'result2'?

Since it is supposed to be an async (AJAX), I'd expect r = 'result1', but from some tests I did, I got r = 'result2'.

What really happens?

Upvotes: 2

Views: 1716

Answers (3)

jfriend00
jfriend00

Reputation: 708046

Asynchronous Ajax calls can return in ANY order. You cannot rely on the order. You can only reliably use the result of an ajax call in the completion handler for THAT particular Ajax call or in some function you call and pass the result to from the completion handler.

You absolutely do NOT want to be putting ajax results into global variables and then try to use them from there. That is a recipe for a timing disaster and is never a good way to code it.

If you want to coordinate the results of multiple ajax calls, you can do a bunch of custom coding yourself to keep track of results in order or you can use a third party library like Async or promises.


If the actual problem you're trying to solve is some sort of incremental search where you may have multiple requests in flight at the same time and you don't want to process a request that is older than something you've already received, then you need to create a system such that keeps track of sequencing so you know when to ignore a response. There are a number of ways to approach that:

  1. You can abort any previous request each time you send a new one.
  2. You can tag each request with a monotonically increasing number and then keep track of the highest response number you've processed so far and ignore any with lower numbers.

FYI, if your server processes each request synchronously (thus it starts on the first one that arrives and isn't available to process any other request until that first one is done) and can only process one request at a time, then it may only return results in FIFO order, regardless of how long each request takes. If, on the other hand, your request processing was asynchronous or your server could process multiple requests at a time, then the request with the shortest execution time will return first.

Upvotes: 4

Barmar
Barmar

Reputation: 782407

AJAX responses will be processed in the order that the responses arrive. The order that they're sent is irrelevant. I've modified your code to log the response, you can see in the Javascript console that the fast query is processed first.

var searchFunction = function(query, delay) {
    $.ajax({
        url: '/echo/json/',
        type: 'POST',
        data: {
            json: JSON.stringify(query),
            delay: delay
        },
        success: function(r) {
            console.log(r);
        }
    });
};

searchFunction('query1', 3);
searchFunction('query2', 1);

jsfiddle demo

Upvotes: 0

Brennan
Brennan

Reputation: 5742

What is r that you are setting? No matter what, you can't expect AJAX (asynchronous by definition) to happen in any sort of order. If you are going to be making multiple calls, and want to store all of the responses, you will want to do something like:

var resultSet = [];

var searchFunction = function(query) {
    $.ajax({
        url: '..',
        type: 'GET',
        data: {
            'query': query
        },
        success: function(result) {
            resultSet.push(result);
        }
    });
};

Upvotes: 0

Related Questions