jQuery-是按顺序收到的ajax响应?

时间:2014-10-23 02:45:11

标签: javascript jquery ajax asynchronous

如果我有类似的话:

var result;

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

r总是最终成为上次searchFunction(query)来电的结果吗?

例如,假设我这样做:

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

我的r'result1'还是'result2'

由于它应该是异步(AJAX),我期待r = 'result1',但是从我做过的一些测试中,我得到了r = 'result2'

究竟发生了什么?

3 个答案:

答案 0 :(得分:4)

异步Ajax调用可以按任意顺序返回。你不能依赖订单。您只能在完成处理程序中可靠地使用ajax调用的结果来执行特定的Ajax调用,或者在您调用的某个函数中将结果传递给完成处理程序。

你绝对不希望将ajax结果放入全局变量中,然后尝试从那里使用它们。这是计时灾难的一个方法,从来都不是编码它的好方法。

如果你想协调多个ajax调用的结果,你可以自己做一堆自定义编码来按顺序跟踪结果,或者你可以使用像Async或promises这样的第三方库。


如果您尝试解决的实际问题是某种增量搜索,您可能同时在飞行中有多个请求,并且您不希望处理比您已经存在的请求更旧的请求收到后,您需要创建一个系统,以便跟踪排序,以便您知道何时忽略响应。有很多方法可以解决这个问题:

  1. 您可以在每次发送新请求时中止任何先前的请求。
  2. 您可以使用单调递增的数字标记每个请求,然后跟踪到目前为止已处理的最高响应数,并忽略任何较低的数字。
  3. 仅供参考,如果您的服务器同步处理每个请求(因此它从第一个到达的请求开始,并且在第一个请求完成之前无法处理任何其他请求)并且一次只能处理一个请求,那么无论每个请求需要多长时间,它都只能以FIFO顺序返回结果。另一方面,如果您的请求处理是异步的,或者您的服务器一次可以处理多个请求,那么具有最短执行时间的请求将首先返回。

答案 1 :(得分:0)

您设置的r是什么?无论如何,你不能指望AJAX(按定义异步)以任何顺序发生。如果您打算进行多次通话,并希望存储所有响应,则需要执行以下操作:

var resultSet = [];

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

答案 2 :(得分:0)

AJAX响应将按响应到达的顺序处理。他们发送的订单无关紧要。我已修改您的代码以记录响应,您可以在Javascript控制台中看到首先处理快速查询。

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