Javascript 防止AJAX队列阻塞浏览器

Javascript 防止AJAX队列阻塞浏览器,javascript,jquery,ajax,Javascript,Jquery,Ajax,注:简化示例 我有一个有1000行表格的页面。对于每一行,我需要通过AJAX调用在服务器上“做一些工作”,然后在回调中,更新表中的行,说“完成” 起初,我尝试在选择器中启动1000个ajax请求,但浏览器被锁定 所以我改变了它,尝试使用一个内部ajax计数器,所以一次只能触发50次 代码如下: $('#do').click(function () { var maxAjaxRequests = 50; var ajaxRequests = 0; var doneCount

注:简化示例

我有一个有1000行表格的页面。对于每一行,我需要通过AJAX调用在服务器上“做一些工作”,然后在回调中,更新表中的行,说“完成”

起初,我尝试在
选择器中启动1000个ajax请求,但浏览器被锁定

所以我改变了它,尝试使用一个内部ajax计数器,所以一次只能触发50次

代码如下:

$('#do').click(function () {
    var maxAjaxRequests = 50;
    var ajaxRequests = 0;
    var doneCounter = 0;
    var toDo = $('#mytable tr').length;

    $.each($('#mytable > tr'), function (i, v) {
        while (doneCounter < toDo) {
            if (ajaxRequests <= maxAjaxRequests) {
                ajaxRequests++;
                doAsyncStuff($(this), function () {
                    ajaxRequests--;
                    doneCounter++;
                });
            } else {
                setTimeout(function() {
                }, 1000);
            }
        }
    });
});

function doAsyncStuff(tr, completeCallback) {   
    $.ajax({
        url: '/somewhere',
        type: 'POST',
        dataType: 'json',
        data: null,
        contentType: 'application/json; charset=utf-8',
        complete: function () {
            completeCallback();
        },
        success: function (json) {
            // update ui.
        },
        error: function (xmlHttpRequest, textStatus, errorThrown) {
            // update ui.
        }
    });
}
$('do')。单击(函数(){
var maxAjaxRequests=50;
var ajaxRequests=0;
var doneCounter=0;
var toDo=$('#mytable tr')。长度;
$。每个($('#mytable>tr'),函数(i,v){
while(doneCounter如果(ajaxRequests您在
中执行
循环,而
中执行每个
回调函数,那么ajax请求比1000多,最糟糕的是1000*1000

您可以用不同的时间延迟每个ajax请求

$('#do').click(function () {
    $('#mytable > tr').each(function (i, v) {
        var $this = $(this);
        setTimeout(function () {
            doAsyncStuff($this, function () {
               console.log('complete!');
            });
        }, i * 10);
    });
});

浏览器被锁定,因为您正在创建一个无休止的循环

while循环反复运行,等待doneCounter增加,但是javascript引擎无法执行ajax的成功调用,因为它被困在while中

var callQueue = new Array();
$('#mytable > tr').each(function(key,elem){callQueue.push($(this));});

var asyncPageLoad = function(){
var tr = callQueue.splice(0,1);
$.ajax({
        url: '/somewhere',
        type: 'POST',
        dataType: 'json',
        data: null,
        contentType: 'application/json; charset=utf-8',
        complete: function () {
            completeCallback();
            asyncPageLoad();
        },
        success: function (json) {
            // update ui.
        },
        error: function (xmlHttpRequest, textStatus, errorThrown) {
            // update ui.
        }
    }
};
asyncPageLoad();

这将一个接一个地调用请求。如果您愿意,只需在内部执行for()循环,以进行5次调用?并在浏览器正常的情况下增加调用量。

实际上,我更喜欢在当前请求完成时发送新请求。我使用此方法转储数据库表()。也许它提供了一个想法


请参见,选中所有复选框,然后单击转储!按钮。您可以找到源代码(请参见
dumpAll
函数)。

如果您成批发送请求,则性能可能会更好。通过单个/更少的HTTP请求。@Mythril-无法做到这一点。每个操作都需要独立。“为什么”超出了这个问题的范围。没有很多好的理由这样做…所以我仍然很好奇为什么…但是也许你可以使用html webworker?我真的不相信你需要为每一行触发一个ajax请求-特别是当同时触发它们时,这表明它们可以捆绑在一起。你真的应该d过度思考您正在做的事情。尽管如此,在ajax调用中使用webworker将是一件好事。但是,您不能使用jQuery,而必须使用本机xmlhttp。请注意,这部分代码产生了一个奇怪的错误,我在IE7和IE8中已经跟踪了3天。POST数据不会随请求和请求一起发送当服务器在几毫秒内做出响应时,浏览器会等待整整60秒才继续。在不同的调用中随机发生。