You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用getjson()控制台返回undefined,无法在onload外访问JSON数据

解决JSON数据异步获取后无法访问的问题

嘿,作为JS新手碰到这个问题太正常啦!咱们先搞清楚问题出在哪:你用的XMLHttpRequest是异步操作——也就是说,当你调用getjsonData的时候,请求还在后台跑呢,根本没等到数据返回就直接结束了,所以控制台才会返回undefined,而且onload函数外面也拿不到数据。

问题根源拆解

异步操作不会阻塞代码执行顺序:你调用retrieveJsonData后,代码会立刻继续往下走,不会等请求完成。只有当请求成功拿到数据后,onload里的代码才会执行。所以你想直接同步获取数据是行不通的,得用异步的方式来处理结果。

解决方案1:用回调函数处理异步结果

咱们可以给函数加个回调参数,等请求完成后把数据传给回调函数:

var DataController = (function(){
  // 私有函数:接受回调函数作为参数
  var retrieveJsonData = function(callback){
    var api = 'http://52.69.49.40/assignment/getServiceData.php';
    var ourRequest = new XMLHttpRequest();
    ourRequest.open('GET', api);
    ourRequest.onload = function(){
      // 记得用let/const声明变量,避免全局污染
      const obj = JSON.parse(ourRequest.responseText);
      // 请求完成后调用回调,把数据传出去
      callback(obj);
    };
    // 别忘了发送请求!
    ourRequest.send();
  };

  // 公开方法:同样接受回调
  return {
    getjsonData: function(callback){
      retrieveJsonData(callback);
    }
  };
})();

// 调用的时候这样用:
DataController.getjsonData(function(data){
  console.log(data); // 这里就能拿到JSON数据啦
  // 后续处理数据的逻辑都写在这里
});

解决方案2:用Promise(更现代的写法)

如果想让代码更清晰,也可以用Promise来封装异步请求,后续还能结合async/await使用:

var DataController = (function(){
  var retrieveJsonData = function(){
    return new Promise(function(resolve, reject){
      var api = 'http://52.69.49.40/assignment/getServiceData.php';
      var ourRequest = new XMLHttpRequest();
      ourRequest.open('GET', api);
      ourRequest.onload = function(){
        if(ourRequest.status >= 200 && ourRequest.status < 300){
          const obj = JSON.parse(ourRequest.responseText);
          resolve(obj); // 请求成功,返回数据
        } else {
          reject('请求出错啦:' + ourRequest.statusText); // 请求失败,返回错误
        }
      };
      ourRequest.onerror = function(){
        reject('网络请求失败');
      };
      ourRequest.send();
    });
  };

  return {
    getjsonData: function(){
      return retrieveJsonData();
    }
  };
})();

// 调用方式1:用.then()
DataController.getjsonData()
  .then(function(data){
    console.log(data);
    // 处理数据
  })
  .catch(function(error){
    console.error(error);
  });

// 调用方式2:用async/await(需要在async函数里)
async function fetchData(){
  try {
    const data = await DataController.getjsonData();
    console.log(data);
  } catch(error){
    console.error(error);
  }
}
fetchData();

额外提醒

  • 原代码里的obj没有用var/let/const声明,会变成全局变量,这是不好的习惯,记得加上变量声明。
  • 别忘了调用ourRequest.send(),不然请求根本发不出去!

内容的提问来源于stack exchange,提问作者junaid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:30:04