$ .each阻止浏览器中的$ .ajax

时间:2015-03-12 16:17:25

标签: javascript jquery ajax each

我有这样的事情:遍历id并为每个人做一个ajax请求(async:true)到服务器(同一个域)并将接收到的数据附加到DOM元素。它不是一项艰巨的任务,它可行。示例代码:

$.each(ids, function (index, id) {
    $.ajax({
        type: 'POST',
        url: "http://localhost/example/"+id,
        success: function (data) {
            $('#content').append(data);
        }
    });
});

我的问题是:当我需要循环许多ID(例如1000)时,它会发送大量的ajax,并且浏览器“冻结”,当我点击链接时,它会等待所有ajax请求完成,然后打开单击的链接。

超时不是一种选择,因为我需要显示尽可能多的接收数据。如果完成需要1秒或者需要100秒,则没有问题,因为用户将看到已完成的其他请求

那么,处理这个问题的最佳方法是什么?点击this之类的链接时停止ajax请求?或者有更好的方法来做到这一点

2 个答案:

答案 0 :(得分:2)

您可以让服务器返回格式为

的json,而不是对应用程序进行1000次ajax调用。
[{ id: 0, content: "A",
id: 1, content: "B",
.
.
id: n, content: "Nth content" }]

请求

var idList = [];
$.each(ids, function(index, id) {
    idList.push(id);
});
$.ajax({
type: "POST",
data: { id: idList },
success: function(data) {
    $.each(data, function(index, v) {
        $("#content").append(v.content);
    })
}).error(function(response) {
    $("#content").append(response);
});
据我所知,Chrome一次可以处理8个并发的ajax请求,像1000这样的数字对它来说太多了。上面的代码会减少ajax调用的数量,从1000减少到1。

但是,如果您确实希望像这样进行1000次调用,那么最好做这样的事情

var idList = [];
$.each(ids, function(index, id) {
    idList.push(id);
});
function makeAjax() {
    $.ajax({
        type: "POST"
        data: { id : idList.pop()},
        success: function(data) {
            $("#content").append(data);
        }
    }).done(function() {
        if(idList.length>0) {
            makeAjax();
        }
    });
}

下面的代码一次最多会产生8个ajax调用。

var idList = [];
$.each(ids, function(index, id) {
    idList.push(id);
});
var MAX_THREADS = 8;
var CURRENT_THREADS = 0;

function makeAjax() {
    CURRENT_THREADS++;
    $.ajax({
        type: "POST"
        data: { id : idList.pop()},
        success: function(data) {
            $("#content").append(data);
        }
    }).done(function() {
        CURRENT_THREADS--;
    });
}

function callAjax() {
    if(CURRENT_THREADS < MAX_THREADS) {
        makeAjax();
    }
    if(idList.length > 0) {
        setTimeout(callAjax, 1000);
    }
}

callAjax();

但是我不建议这样做。如果一次获取所有ID的内容需要花费很长时间,那么最好使用其他一些解决方案,例如分页。

答案 1 :(得分:0)

更好的方法是改变您请求数据的方式。

如果可能的话,尝试更改服务器以接受多个ID,并同时发出一个包含所有ID的请求。这样,您就可以循环访问数据而不是AJAX请求。

想一想。对于1000个ID的数组,每次执行该功能时,您至少要发出1001个请求(页面为1!)。如果该请求由数据库支持,那就是1000个单独的数据库命中。

现代网络浏览器只会处理这么多同步的AJAX请求,然后排队等待以后处理。在您提供的代码中,可能没有提高性能的好方法。