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

JavaScript函数外部无法访问异步获取的数据问题求助

异步数据访问后无法直接获取属性值

我在处理数据访问时遇到了问题,以下是我的代码片段:

$.each(response.data.tree, function (i) {
  // 只处理文件类型
  if (this.type == 'blob') {
    // 初始化变量
    var link = null,
      content = null;

    // 构造文件内容的访问链接
    link =
      'https://raw.githubusercontent.com/jkulikowski84/Code/main/' +
      this.path.replace(/ /g, '%20');

    let data = [];

    async function getCode() {
      // 请求文件内容
      const response = await fetch(link);
      // 转换为文本格式
      const data = await response.text();
      // 将数据存入数组
      addData(link, data);
    }

    function addData(link, object) {
      data['link'] = link;
      data['code'] = object;
    }

    // 调用异步获取数据的函数
    getCode();

    console.log(data);
  }
});

当我在控制台打印data时,能看到预期的内容,但尝试直接通过console.log(data['code'])或console.log(data['link'])访问时,却返回undefined。请问如何在函数外部直接访问这些code和link数据?


问题原因

核心问题是异步操作的执行顺序:getCode()是异步函数,调用它之后代码会立刻执行console.log(data),此时fetch请求还未完成,addData也还没被调用,data仍是空数组。控制台能看到预期内容是因为浏览器会实时更新对象的预览,但实际代码执行时属性还未被赋值。

解决方案

要在异步操作完成后再访问数据,有两种常用方式:

  1. 在数据更新后处理逻辑
    把需要使用data的代码放到addData函数内,确保数据准备好后再执行:

    function addData(link, object) {
      data['link'] = link;
      data['code'] = object;
      // 在这里处理数据,比如打印或渲染到页面
      console.log(data['code']);
    }
    
  2. 用async/await等待异步完成
    将$.each的回调改为异步函数,等待getCode执行完毕后再访问数据:

    $.each(response.data.tree, async function (i) {
      if (this.type == 'blob') {
        let link = 'https://raw.githubusercontent.com/jkulikowski84/Code/main/' + this.path.replace(/ /g, '%20');
        let data = {}; // 这里用对象更合理,因为存储的是键值对而非数组元素
    
        async function getCode() {
          const response = await fetch(link);
          const code = await response.text();
          data.link = link;
          data.code = code;
        }
    
        await getCode(); // 等待异步请求完成
        console.log(data.code); // 此时可正常访问属性
      }
    });
    

2024年6月7日更新:优化后的GitHub仓库搜索实现

经过尝试后,我找到了更高效的实现方式。我的需求是构建一个自定义函数,能够在GitHub仓库中搜索关键词并将对应数据拉取到网站上。最初的代码效率很低,会遍历每个文件并发起超过90次请求。

新代码仅通过1次仓库目录树请求获取所有文件信息,再批量处理文件内容请求,速度更快:

function handle(e) {
  // 获取当前激活页面
  var ActivePage = $('div.page.active');
  
  // 默认显示所有目录内容
  ActivePage.find('li.back, li.dir, li.file').css('display', '');
  
  // 获取搜索框输入内容
  var Search_Code = (($('div.page.active').find("#Search_Code"))[0]).value;
  // 配置不区分大小写的全局正则搜索规则
  var Search = new RegExp(Search_Code, 'gi');

  // 每次搜索前清空旧结果
  jQuery('div[class="SearchResults"]').remove();

  // 创建搜索结果展示容器
  ActivePage.find('li.titles').after($('<div class="SearchResults">'));               
  
  // 按下回车键且搜索内容不为空时执行搜索
  if((e.keyCode === 13) && (Search_Code)) {
    var _this = this;

    // 请求仓库完整目录树(递归获取所有文件节点)
    $.ajax({
      url: 'https://api.github.com/repos/jkulikowski84/Code/git/trees/main?recursive=1',
      type: 'GET',
      data: {},
      dataType: 'jsonp',
      success: function(response){
        // 遍历所有目录节点
        $.each(response.data.tree, function(i){
          // 只处理文件类型节点
          if(this.type == 'blob') {
            // 构造文件内容的访问链接
            var link = "https://raw.githubusercontent.com/jkulikowski84/Code/main/" + (this.path).replace(/ /g,"%20");
            
            // 请求文件内容并匹配关键词
            $.ajax({
              url: link,
              type: 'GET',
              data: {},
              dataType: 'text',
              success: function(response){
                // 匹配关键词(文件内容或链接中包含)
                if ((response).match(Search) || (link).match(Search)) {
                  // 隐藏原始目录,显示搜索结果
                  ActivePage.find('li.back, li.dir, li.file').css('display', 'none');
                  // 将匹配的文件链接添加到结果容器
                  ActivePage.find('div.SearchResults').append($('<li class="SearchResults">' + link + '</li>'));
                }
              },
              error : function(response){
                if(console && console.log)
                  console.log('Request Error:', response);
              }
            });
          }
        });
      },
      error : function(response){
        if(console && console.log)
          console.log('Request Error:', response);
      }
    });
  }
  return false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:00:59