javascript - 使用 XMLHttpRequest 解析 JSON 时返回空值

标签 javascript json typescript

我现在一直在尝试从 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/

相关文章:

angular2单元测试: cannot read property of componentInstance.方法()未定义

javascript - 邀请 friend 后Facebook连接重定向

typescript 复制文件

javascript - 快速处理空的 req.body?

android - StringEntity/string 到 HttpEntity

asp.net-mvc - knockout 日期在发布到 MVC Controller 时重置

json - 如何在 JQ 中有条件地将字符串值更改为数字?

javascript - 在 TypeScript 中重构单页 Web 应用程序

javascript - JavaScript 或 Jquery 中的 onchange 事件

javascript - 为什么分析数组的大小需要是 fftSize 又名FrequencyBinCount 的一半