[英]JavaScript Synchronous Ajax Request Idiosyncrasies
如果我以“怪异”的方式做事,我想为此道歉,因为我主要是C开发人员,并且正在以与C中相同的方式解决AJAX问题。
我有一个脚本,该脚本将连接到“推送服务器”,该脚本将等待消息可用,然后仅发送该一条消息并断开连接。 然后,客户端必须重新建立连接以侦听将来的消息。
我试图通过在异步回调中实现同步 AJAX调用来做到这一点,并且它工作正常,但它似乎会阻止DOM(也许是吗?我在这里展示了我对JS的无知)会阻塞,直到所有调用都完成为止。
我不知道如何使用纯异步调用来完成此操作,因为我不想每次都有一个调用回调的回调而最终耗尽堆栈。
这是代码:
$.ajax({
url: './recoverDevice',
data: JSON.stringify(requestData),
dataType: 'json',
type: 'POST',
success: function(j)
{
console.log(j);
if (j.success)
{
//Indefinitely listen for push messages from the server
var loopMore = true;
while(loopMore)
{
$.ajax({
async: false,
url: './getPendingMessage',
dataType: 'json',
type: 'POST',
success: function(j)
{
//alert(j.message);
$("#progressBox").append("<li>" + j.message + "</li>");
loopMore = !j.complete;
}
});
}
}
else
{
$("#errorBox").show();
$("#errorBox").text(j.errorMessage);
}
}
});
现在,从逻辑上讲,此代码应该可以正常工作。 在异步函数中,我遍历一个同步 JS调用,每次收到一条消息时,我都会将其附加到DOM,只有当服务器告诉我不再有消息时,我才退出循环,结束异步线程并完成任务。
问题在于,一旦收到所有消息,DOM访问似乎就全部合并了。 即,仅当接收到所有消息并且退出异步线程后,才执行附加操作。
注释掉的alert
是一个测试-效果很好 。 在每条通知之后,我都会看到一个消息框,它会正确暂停,直到出现下一条消息为止(其余代码保持原样)。
我猜想这是我的浏览器(Chrome)通过禁止在异步线程退出之前才允许DOM操作来保护自己免受竞争情况的魔力吗? 还是我偏离常规,在这里吠错了树?
摆脱循环并将async
设置为true可以正确接收第一个消息(那里没有问题),但是此后显然没有消息。
显然我可以做这样的事情:
function GetMessage()
{
$.ajax({
async: true,
url: './getPendingMessage',
dataType: 'json',
type: 'POST',
success: function(j)
{
$("#progressBox").append("<li>" + j.message + "</li>");
if (!j.complete)
{
GetMessage();
}
}
});
}
但是,随着时间的推移,这会导致堆栈溢出(不是吗?)。
一个明显的解决方案是也可以在此处使用异步调用,但是通过某种同步原语来发信号通知while循环暂停并继续进行新的调用,但是看起来JS没有信令原语?
想通了这一点-我不知道为什么以前没有看到这个,但是我后面的代码片段可以完美地工作。 在发布时我还没有意识到,但是它不会溢出堆栈,因为每次运行它都会启动一个异步调用并退出-因此堆栈框架的深度永远不会超过2或3。 异步调用是从外部管理的,并且不会在堆栈上,因此每次重新启动时都如此。
对于第一个方法(异步调用中的同步代码)为何不起作用/为何不起作用的任何输入,我仍然将不胜感激。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.