注意:简化示例..
我有一个包含1000个表行的页面。对于每一行,我需要通过AJAX调用在服务器上“做一些工作”,然后在回调中更新表格行说完。
最初,我尝试在.each
选择器内触发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.
}
});
}
但浏览器仍被锁定。它永远不会进入$.ajax
完整的回调,即使我可以看到请求成功返回(通过Fiddler)。因此它只是睡眠,循环,睡眠等因为回调永远不会返回。
我觉得整个doAsyncStuff
函数需要是异步的吗?
关于我做错了什么的想法(或者我如何做得更好)?
答案 0 :(得分:1)
你正在while
回调函数中进行.each
循环,因此有超过1000的ajax请求,最差的是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);
});
});
答案 1 :(得分:0)
浏览器因为WHILE而被锁定......你正在创建一个无限循环。
while循环一遍又一遍地运行,等待doneCounter增加,但是javascript引擎无法执行ajax的成功调用,因为它被卡住了......
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次调用?如果浏览器没问题,请增加金额。
答案 2 :(得分:0)
实际上,我更喜欢在当前请求完成时发送新请求。我使用此方法来转储数据库表(in this work)。也许它会给出一个想法。