繁体   English   中英

Javascript:同步使用异步AJAX

[英]Javascript: Using asynchronous AJAX synchronously

首先,我研究了相关的SO问题,但是没有找到合适的答案,因此这里有:

我一直在研究HTML / Javascript页面,该页面充当后端服务器的UI。 在使用AJAX中的同步调用的所有过程中,我都取得了不错的进步(又名var xmlhttp = new XMLHttpRequest(); xmlhttp.open(type, action, false); ),但是现在发现Mozilla显然是不喜欢同步请求,因此已经淘汰了一些急需的功能。

引用https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

注意:从Gecko 11.0(Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8)以及WebKit build 528开始,这些浏览器不再允许您在执行同步请求时使用responseType属性。 尝试这样做会引发NS_ERROR_DOM_INVALID_ACCESS_ERR异常。 已经向W3C提出了此更改以进行标准化。

太好了。 我将需要有条件地更改响应类型,但是它将不起作用。 现在我打算在的东西 ,将模拟同步来包装一个AJAX异步请求。

以下是我的代码使用的通用“生成Web请求”功能,我已经开始对其进行调整以适合我的目的。 不幸的是,它的运行不像我希望的那样。

var webResponse = null;

function webCall(action, type, xmlBodyString) {
console.log("In webCall with " + type + ": " + action);
webResponse = null;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
    if (xmlhttp.readyState == 4)
    {
        if (xmlhttp.status == 200) {
            webResponse = xmlhttp.responseXML;
        } else {
            var statusTxt = xmlhttp.statusText;
            if (statusTxt == null || statusTxt.length == 0) {
                statusTxt = "An Unknown Error Occurred";
            }
            throw "ERROR " + xmlhttp.status + ":" + statusTxt;
        }
    }
}
xmlhttp.open(type, action, true);
if (xmlBodyString == null) {
    xmlhttp.send();
} else {
    xmlhttp.setRequestHeader("Content-Type", "text/xml");
    xmlhttp.send(xmlBodyString);
}

for (var i = 0; i < 20; i++) {
    if (webResponse != null) {
        break;
    }
    window.setTimeout(nop, 250);
}
if (webResponse == null) {
    throw "Waited 5 seconds for a response, and didn't get one.";
}
console.log("Responding with " + webResponse);
return webResponse;
}

function nop() {
}

因此,我认为这很简单。 创建一个全局变量(回想起来,它可能甚至不必是全局变量,但现在是w / e),设置onreadystatechange以在它准备好后为其分配一个值,发出我的异步请求,等待一个最大值5秒后,全局变量将不为null,然后将其返回或抛出错误。

问题是我的代码实际上没有等待5秒钟。 相反,它立即退出,声称它等待了5秒钟才这样做。

我做了一个小提琴,因为它值得。 它在那里也不起作用。 http://jsfiddle.net/Z29M5/

非常感谢您的协助。

你做不到 坚持异步请求。 回调地狱很烂,但这就是您在没有语言支持的事件驱动系统中所得到的。

目前,根本没有办法在浏览器中的普通JavaScript中模拟同步代码。

如果您可以严格限制受支持的浏览器集(在AFAIK中现在仅是 Firefox),则可以使用生成器来获得同步外观的代码。

也有一些语言可以编译成JS并支持外观同步的代码。 我可以想到的一个示例(几年前)是: https//github.com/maxtaco/tamejs

首先,尽管痛苦不堪,但异步使用异步代码是必经之路。 采取了不同的方法,仅此而已。

其次,对于您的特定问题,这是您的“延迟”循环的作用:

For twenty iterations
  if we've had a response, break
  set a timeout for 250ms
go round again

(整个for循环会立即完成所有20次迭代。您将没有响应)

250ms后

执行第一个setTimeout回调,即nop

执行第二个...

除了将您的处理代码放入AJAX回调中,我想不到一种解决此问题的快捷方法,无论如何,这应该是异步代码所在的地方。

为什么不创建一个请求数组,并在收到上一个ajax调用的响应时逐个弹出请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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