按顺序收集AJAX结果

Posted

技术标签:

【中文标题】按顺序收集AJAX结果【英文标题】:Collect AJAX results in order 【发布时间】:2016-12-09 06:00:35 【问题描述】:

我有一个值数组 (myarray),我想遍历并在每次迭代时运行 AJAX 请求。我已将每个 ajax 请求放在另一个数组 (requests) 中,以便在所有 AJAX 请求完成后调用alert

像这样:

var requests = [];
for (i = 0; i < myarray.length; ++i) 
    requests.push($.ajax(
        url: 'anotherurl?=' + myarray[i],
        dataType: "JSONP",
        success: function (data) 
          array_of_results.push(data);
        
    ));

$.when.apply($, requests).done(function() 
    alert('complete');
);

所有结果都收集在array_of_results。但是由于 AJAX 请求需要不同的时间来完成,所以这个数组没有原始顺序的结果。

有没有办法订购这个数组?

我希望我说得有道理。我很欣赏这是相当复杂的。

【问题讨论】:

ajax 在 for 循环中调用。有必要吗? 最好使用 Promises 来完成这项工作。比如将你的数组映射到一个promise数组(比如myPromiseArray),然后调用Promise.all(myPromiseArray).then(onFulFillment, onReject),其中onFulfillmentonReject回调将被提供来自promise的原始顺序的结果数组。跨度> Asi 理解 $.ajax() 调用返回一个 jqXHR 对象,该对象自 V1.5 起包含 Promise 接口的所有属性、方法和行为。因此,实现我在上述评论中提到的内容应该是一种幸福。更多关于api.jquery.com/jquery.ajax/#jqXHR 【参考方案1】:

您是否尝试过以下方法?我认为这应该有效。所有响应都应该按顺序在when() 的成功函数中可用。

var requests = [];
for (i = 0; i < myarray.length; ++i) 
    requests.push($.ajax(
        url: 'anotherurl?=' + myarray[i],
        dataType: "JSONP"
    ));

$.when.apply($, requests).done(function() 
    array_of_results = arguments;
    alert('complete');
);

【讨论】:

成功时(每个 ajax 调用)会错过将数据推送到 array_of_results 我已经纠正了我的例子。需要使用特殊的JS关键字“arguments”以数组的形式获取成功函数参数。 好的..但是顺序将是返回的ajax调用而不是调用的顺序 没有。它应该与您将调用添加到 requests 数组的顺序相同 好的,我想念“when.apply”等待所有请求都解决然后调用“done”函数..【参考方案2】:

您可以将自定义属性添加到您的 $.ajax 对象,设置为您的 i var。

var requests = [];
for (i = 0; i < myarray.length; ++i) 
    requests.push($.ajax(
        url: 'anotherurl?=' + myarray[i],
        dataType: "JSONP",
        myCustomIndex: i,
        success: function (data) 
          array_of_results[this.myCustomIndex] = data;
        
    ));

$.when.apply($, requests).done(function() 
    alert('complete');
);

javascript 真的很宽松,如果你给一个数组赋值超出了它的范围(大于 0),数组的大小将自动设置为正确的数量。

【讨论】:

我认为“i”值始终是“for”循环的最后一个值(见闭包...)【参考方案3】:

以@Christo 的回答为基础 - 使用数组映射函数

var array_of_results = [];
var requests = myarray.map(function(item, index) 
    return $.ajax(
        url: 'anotherurl?=' + item,
        dataType: "JSONP",
        success: function (data) 
            array_of_results[index] = data;
        
    
);

...

【讨论】:

为什么投反对票?这是非常好的代码,只是因为克里斯托删除了他的答案并不会降低这个答案的有效性 - 匿名懦夫不加解释地投反对票【参考方案4】:

如何使用异步设置为 false 的 jquery.ajax 调用。这样,响应将按要求按顺序排列...

【讨论】:

它将挂起浏览器并停止其他进程:) 另外,我很确定它已被弃用。上次尝试 sjax 时,我觉得我在控制台中看到了这样的消息..【参考方案5】:

考虑使用递归而不是使用循环。这是一个完整的例子:

var myArray = [
    "somevalue",
    "some other value",
    "another value"
];
var i = myArray.length;
var responses = [];

function doRequests()
    i--;
    $.ajax(
        url: "myurl.php",
        data: paramname: myArray[i]
    ).done(function(response)
        responses.push(response);
        if(i>0) doRequests();
        else
            // all requests sent.. do stuff
            // responses array is in order
            console.log(responses);
            alert("all done!");
        
    );

【讨论】:

以上是关于按顺序收集AJAX结果的主要内容,如果未能解决你的问题,请参考以下文章

reactjs/flux:按顺序执行动作(ajax)

在不使用同步Ajax的情况下使数据按顺序排列

C/C++编译错误收集-Wreorder成员未按顺序初始化

无法按顺序触发两个 jQuery ajax 调用

来自 Ajax 源的 DataTables 按数据顺序排序并显示格式化日期

如何确保JavaScript的执行顺序