首先,我查看了相关的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 :
Note: Starting with Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8), as well as WebKit build 528, these browsers no longer let you use the responseType attribute when performing synchronous requests. Attempting to do so throws an NS_ERROR_DOM_INVALID_ACCESS_ERR exception. This change has been proposed to the W3C for standardization.
那太好了。我需要有条件地更改响应类型,但它不起作用。现在我打算将 AJAX 异步请求包装在模拟同步性的东西中。
以下是我的代码使用的通用“发出网络请求”函数,我已开始对其进行调整以适应我的目的。不幸的是,它并没有像我希望的那样工作。
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 秒。
我做了一把 fiddle ,无论它的值(value)如何。它在那里也不起作用。 http://jsfiddle.net/Z29M5/
非常感谢任何帮助。
最佳答案
你做不到。坚持异步请求。回调 hell 很糟糕,但这就是在没有语言支持的事件驱动系统中所得到的。
目前根本没有办法在浏览器中用纯 JavaScript 模拟同步代码。
如果您可以严格限制您支持的浏览器集(据我所知,目前只有 Firefox),您可以通过使用生成器来获得同步外观代码。
还有一些语言可以编译为 JS 并支持同步代码。我能想到的一个例子(几年前)是这样的:https://github.com/maxtaco/tamejs
关于Javascript:同步使用异步 AJAX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19260807/