我一直在尝试从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中的范围有关但现在被困在这里几个小时没有进展我无能为力。
正如我在xmlHttp.onreadystatechange = function()中提到的,console.log实际上是记录正确的值。只是在函数开头创建的obj变量没有得到值。
答案 0 :(得分:4)
AJAX是异步的。这意味着onreadystatechange
函数将在稍后阶段调用,可能是在您从Parse
方法返回之后。因此,您不应该尝试从obj
方法返回Parse
。您希望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应用程序时,你应该停止考虑顺序函数,你将一个接一个地调用它们并返回值。你应该开始考虑回调。
答案 1 :(得分:0)
您需要将回调传递给函数:
static Parse(url: string, onSuccess: Function): Object{
Asserts.isUrl(url, 'URL is invalid');
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var obj = new Object();
obj = JSON.parse(xmlHttp.responseText);
onSuccess(obj)
}
}
};
xmlHttp.open('GET', url, true);
xmlHttp.timeout = 2000;
xmlHttp.ontimeout = function () {
xmlHttp.abort();
throw new Error("Request Timed Out.");
};
xmlHttp.send();
}
并使用您的回调参数调用该函数。