如何从函数中返回XMLHttpRequest响应?

7

值没有被替换,函数返回0。如何修复?(react-native 0.30,IOS 10.0模拟器)

export function getCategoryList() {
  var xhr = new XMLHttpRequest();
  jsonResponse = null;

  xhr.onreadystatechange = (e) => {
    if (xhr.readyState !== 4) {
      return;
    }

    if (xhr.status === 200) {
      console.log('SUCCESS', xhr.responseText);
      jsonResponse = JSON.parse(xhr.responseText);
    } else {
      console.warn('request_error');
    }
  };

  xhr.open('GET', 'https://httpbin.org/user-agent');
  xhr.send();

  return jsonResponse;
}


1
该请求是异步的,这意味着请求被发送后,您的函数将返回一个空值,然后一段时间后请求才会完成。考虑将回调函数传递给getCategoryList()(简单)或使用Promise(有点困难,但不是很难)。 - Reinstate Monica Cellio
6
阅读:https://dev59.com/RGYq5IYBdhLWcg3wwDRA该文讨论如何从异步调用中返回响应。 - Ivan Chernykh
你应该寻找Promise - Olivier Boissé
2个回答

8
您不能那样返回值。我建议使用回调函数或者Promise来解决:
回调函数:

function getCategoryList(callback) {
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = (e) => {
    if (xhr.readyState !== 4) {
      return;
    }

    if (xhr.status === 200) {
      console.log('SUCCESS', xhr.responseText);
      callback(JSON.parse(xhr.responseText));
    } else {
      console.warn('request_error');
    }
  };

  xhr.open('GET', 'https://httpbin.org/user-agent');
  xhr.send();
}

getCategoryList(data => console.log("The data is:", data));

承诺:

function getCategoryList() {
  var xhr = new XMLHttpRequest();

  return new Promise((resolve, reject) => {

    xhr.onreadystatechange = (e) => {
      if (xhr.readyState !== 4) {
        return;
      }

      if (xhr.status === 200) {
        console.log('SUCCESS', xhr.responseText);
        resolve(JSON.parse(xhr.responseText));
      } else {
        console.warn('request_error');
      }
    };

    xhr.open('GET', 'https://httpbin.org/user-agent');
    xhr.send();
  });
}

getCategoryList().then(res => console.log("The result is", res));


那么使用AJAX,这意味着没有办法像getCategoryList()这样简单的函数调用来返回数据吗?这将更加方便。 更新:看起来最接近的解决方案是使用async/await,但是你仍然不能直接调用该函数,必须在函数名之前使用await关键字调用它(即使你将await函数调用嵌套在另一个函数中,也需要使用await来调用其他函数):https://dev59.com/LVUM5IYBdhLWcg3wWvLF#48969580 - baptx

1
如果XHR是同步的(xhr.open('GET', 'https://httpbin.org/user-agent', false)),你可以返回请求响应,做一个无限循环,在请求完成时中断。
注:
  • 同步XHR已被弃用;
  • 无限循环会在XHR未完成时停止页面(例如,游戏)。

function getCategoryList() {

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "https://httpbin.org/user-agent", false);
    xhr.send();

    // stop the engine while xhr isn't done
    for(; xhr.readyState !== 4;)

    if (xhr.status === 200) {

        console.log('SUCCESS', xhr.responseText);

    } else console.warn('request_error');

    return JSON.parse(xhr.responseText);
}

2
不支持同步的http请求。 - kaminarifox
@iwasmusic,它们已经被弃用了,将来会被移除。这就是你想要的(“如何从XMLHttpRequest响应中返回响应”)。 - user5066707

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接