Javascript:同步使用异步 AJAX

标签 javascript ajax asynchronous

首先,我查看了相关的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/

相关文章:

ruby-on-rails - ajax 调用在 rspec 测试中失败

c# - 在库中编写同步和异步方法并保持 DRY 的模式

javascript - 使可拖动元素落在目标上

javascript - JS 有语法错误

javascript - JS : cross-domain POST, 不需要响应

php - 从 jQuery AJAX 调用的列表项中获取值和名称

java - @Singleton @Startup 完全异步?

c# - CloudTable 异步执行查询

javascript - 关于如何在phonegap中设置sqlite DB的说明

javascript - 使用超时来做跳转功能