繁体   English   中英

JavaScript同步Ajax请求特质

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM