我现在一直在尝试从 API 解析一些 JSON,当我使用它时一切正常
xmlHttp.open('GET', url, false);
但是当我后来想使用请求超时来扩展我的代码时,我的函数开始返回空值。
这是执行实际解析的函数:
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
obj = JSON.parse(xmlHttp.responseText);
console.log(obj);
}
}
};
当我使用 console.log 记录此处返回的对象时,我通常将 JSON 打印到控制台,但稍后在我的函数中我返回了 obj 变量,但它始终为空。
这是整个函数:
static Parse(url: string): Object{
Asserts.isUrl(url, 'URL is invalid');
var obj = new Object();
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
obj = JSON.parse(xmlHttp.responseText);
//console.log(obj);
}
}
};
xmlHttp.open('GET', url, true);
xmlHttp.timeout = 2000;
xmlHttp.ontimeout = function () {
xmlHttp.abort();
throw new Error("Request Timed Out.");
};
xmlHttp.send();
return obj;
}
我最初以为它与 Javascript 中的作用域有关,但现在在这里卡了几个小时没有任何进展后,我毫 headless 绪。
正如我在 xmlHttp.onreadystatechange = function () 中提到的,console.log 实际上记录了正确的值。只是在函数开始时创建的 obj 变量没有获取到值。
最佳答案
AJAX 是异步的。这意味着 onreadystatechange
函数将在更晚的阶段被调用,可能是在您已经从 Parse
方法返回之后。因此,您不应尝试从 Parse
方法返回 obj
。您宁愿让 Parse
方法采用一个附加参数来表示您将在 onreadystatechange
事件中调用的回调函数,并将结果对象传递给它。
我的意思是:
static Parse(url: string, done: (obj: any) => void): void {
Asserts.isUrl(url, 'URL is invalid');
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var obj = JSON.parse(xmlHttp.responseText);
// Pass the resulting object to the callback function
done(obj);
}
}
};
xmlHttp.open('GET', url, true);
xmlHttp.timeout = 2000;
xmlHttp.ontimeout = function () {
xmlHttp.abort();
throw new Error("Request Timed Out.");
};
xmlHttp.send();
}
下面是调用 Parse
函数的方式:
Parse('http://foobar', function(obj) => {
// TODO: do something with obj here
console.log(obj);
});
所以基本上,当您编写使用异步 AJAX 调用的 javascript 应用程序时,您应该停止考虑将一个接一个地调用并返回值的顺序函数。您应该开始考虑回调。
关于javascript - 使用 XMLHttpRequest 解析 JSON 时返回空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34579144/