阻止AJAX队列阻止浏览器
Prevent AJAX Queue from blocking browser
注意:简化示例。。
我有一页有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
函数需要异步?
关于我做错了什么(或者我如何才能做得更好),有什么想法吗?
您正在.each
回调函数中执行while
循环,因此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。。。你正在创造一个无尽的循环。
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次调用?如果浏览器正常,请增加金额。
实际上,我更喜欢在当前请求完成后发送新请求。我使用这个方法来转储数据库表(在这项工作中)。也许它给出了一个想法。
查看此链接,选中所有复选框,然后单击转储!按钮您可以在这里找到源代码(请参阅dumpAll
函数)。
相关文章:
- 访问布局信息是否也会导致浏览器重排
- 内部分区字体大小获胜'调整浏览器窗口大小时不会随媒体查询而更改
- 如何使用phaser使html5游戏在移动设备浏览器上运行
- 有时数据是't显示在浏览器中
- 使图像在单击时展开到不大于浏览器
- fetch() 函数未在 Ubuntu Chromium 浏览器上定义
- 不同浏览器中的空白字符正则表达式行为
- 在Windows 10中自动执行例行程序(主要与浏览器交互)
- Windows形成web浏览器控件和Javascript更改的DOM
- 如何临时暂停浏览器渲染,然后恢复整个页面
- 使用angularjs向浏览器发送servlet响应(下载功能)
- 是什么让一个“;Uncaught RangeError:超过了最大调用堆栈大小“;错误(Chrome,在其他浏览器中显示
- 谷歌地图API v3不适用于移动浏览器或PhoneGap
- 如何处理node.js节点mongodb中的连接和查询队列
- 禁用(而不是隐藏)浏览器滚动条
- jquery代码在Mozilla中有效,但在其他浏览器上无效
- 阻止AJAX队列阻止浏览器
- 使用Javascript和AJAX到Web Service的浏览器内FIFO队列
- 使用浏览器下载队列中的多个文件
- 浏览器中的事件循环和任务队列之间有区别吗