使用XMLHttpRequest

时间:2016-01-03 17:00:35

标签: 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中的范围有关但现在被困在这里几个小时没有进展我无能为力。

正如我在xmlHttp.onreadystatechange = function()中提到的,console.log实际上是记录正确的值。只是在函数开头创建的obj变量没有得到值。

2 个答案:

答案 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();

}

并使用您的回调参数调用该函数。