Javascript 使用XMLHttpRequest解析JSON时返回空值
我现在一直在尝试从API解析一点JSON,当我使用Javascript 使用XMLHttpRequest解析JSON时返回空值,javascript,json,typescript,Javascript,Json,Typescript,我现在一直在尝试从API解析一点JSON,当我使用 xmlHttp.open('GET', url, false); 但当我后来想使用请求超时来扩展代码时,我的函数开始返回空值 这是执行实际解析的函数: xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { obj = JSON.pars
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;
}
Parse('http://foobar', function(obj) => {
// TODO: do something with obj here
console.log(obj);
});
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();
}
我最初认为它与Javascript中的作用域有关,但现在在这里停留了几个小时而没有任何进展之后,我就不知所措了
正如我在xmlHttp.onreadystatechange=函数()中提到的,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
函数:
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;
}
Parse('http://foobar', function(obj) => {
// TODO: do something with obj here
console.log(obj);
});
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();
}
因此,基本上,当您编写一个使用异步AJAX调用的javascript应用程序时,您应该停止考虑将一个接一个地调用并返回值的顺序函数。您应该开始考虑回调。您需要将回调传递给函数:
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;
}
Parse('http://foobar', function(obj) => {
// TODO: do something with obj here
console.log(obj);
});
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();
}
并使用回调参数调用函数。如何使函数等待onreadystatechange并返回正确的值?或者还有其他更好的解决方案吗?如果你让它等待,那么你就完全扼杀了AJAX的全部目的,而AJAX本来就是异步的。有关如何编写
Parse
函数以使其不返回任何值而使用回调的示例,请参阅我的更新答案。我正在构建一个库,该库正在致力于API。因此,这种方法仍然适用于该目的?另外,您是否有任何我可以阅读的关于同步和异步之间的区别的资源?是的,使用回调是编写异步代码的正确方法。你将组织你的库方法,使它们与回调一起工作。那么我是否需要让我的当前函数返回一个对象?难道我不能让它变成一个空白,完全依赖回调吗?