我使用jQuery做一些异步后台数据获取。我偶然发现了这个问题,在第一个请求处理程序完成之前,对同一个URL的多个并行请求没有完成。
我创建了一个简单的例子来演示这个问题:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
</head>
<body>
<button id="js">Click me!</button>
<div>Request 1: <span id="resp1">-</span></div>
<div>Request 2: <span id="resp2">-</span></div>
<script type="text/javascript">
$('#js').click(function() {
$('#resp1, #resp2').html('...');
$.ajax({
url : 'http://stackoverflow.com',
async : true,
complete: function(request, textStatus) {
$('#resp1').html('complete');
alert('The second request is not completed, until you close this alert!');
}
});
$.ajax({
url : 'http://stackoverflow.com',
async : true,
complete: function(request, textStatus) {
$('#resp2').html('complete');
}
});
});
</script>
</body>
</html>
单击按钮后,将生成两个并行的AJAX请求。第一个正常完成,但第二个没有,直到第一个的警报关闭。如果将第二个ajax请求移动到第一个ajax请求的完整事件处理程序中,问题仍然存在。
这是一个错误还是一个功能? 有解决方法吗?
修改
好的,我明白alert()会导致问题。但是我无法解释其他两件事。
当我将第二个ajax-call移动到第一个的完整处理程序(在alert()之前)并将第一个ajax-call更改为async:false时,它就可以了。警报()不应该导致同样的问题吗?
警报必须比Browsers JS-Thread阻止更多,因为如果我在另一个选项卡中打开AJAX-Request,它仍然无法加载,直到我关闭第一个选项卡中的alert-Box。 JS没有参与这里。奇怪。这可能是另一个问题吗?
答案 0 :(得分:1)
这是预期的。 alert()
阻止执行直到它关闭。
执行这些行时会发生什么
$('#resp1').html('complete');
alert('The second request is not completed, until you close this
是第一行触发ajax请求,但是下一行的执行如此之快,以至于ajax请求没有时间完成。一旦模态警报对话框初始化,执行就会暂停。 ajax请求可能处于仍然检索响应的状态,可能正在处理它,但它会暂停,直到警报关闭。
答案 1 :(得分:1)
完成与否的整个前提纯粹基于执行异步请求之间的竞争条件,因为第一个异步请求的回调中的alert()
。如果第二个请求比第一个请求快(足够快以弥补它在第一个请求之后启动的事实)那么你就不会看到你关注的是什么
关于#1不,这不会是相同的,因为当您在警报之前进行ajax调用并且使用async : false
时,ajax请求将在完成之前完成(到警报)。换句话说,您在此处完全同步,因为您处于唯一异步事件的回调中。顺便说一下,不要使用async: false
。
如前所述,alert()
正在阻止执行。
仅供参考,您可以使用它来制作小提琴并使用计时 - 请注意在请求的delay
对象中使用data
。请注意,在此示例中,由于我设置的时间,两者是如何完成的,但如果您将其反转,则在alert()
被清除之前它将无法完成。
最后不要使用alert()
!!