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

使用getDocs获取数据库数据后,无法在then()外部访问数组数据

问题出在异步代码的执行顺序上

getDocs是异步请求,它不会阻塞后续代码执行——调用getDocs后,浏览器会继续运行后面的同步代码,而.then()里的逻辑要等数据库请求完成、拿到数据后才会触发。

你在.then()外面写的console.log(totalDB2['road1'])是同步代码,会比.then()里的赋值逻辑先执行,这时候totalDB2里还没数据,自然返回undefined。

另外提个小细节:你用数组totalDB2存键值对(用road1这种字符串当索引)不太合适,数组是用来存有序的数字索引数据的,换成普通对象{}更合理。

解决办法

办法1:把用数据的逻辑全放到.then()里

如果你的业务逻辑只需要在数据加载完后执行,直接把代码塞到.then()回调里就行:

const totalDBPromise2 = getDocs("Road");
let totalDB2 = {}; // 换成对象

totalDBPromise2.then((querySnapshot) => {
  querySnapshot.forEach((doc) => {
    const data = doc.data();
    totalDB2[data.name] = data; // 对象直接赋值,不用判断includes
  });
  console.log(totalDB2['road1']); // 正常拿到结果
  // 所有需要用totalDB2的代码都写在这
});

办法2:用async/await写同步风格的异步代码

这个写法更直观,避免回调嵌套:

async function loadRoadData() {
  let totalDB2 = {};
  // 等待getDocs请求完成
  const querySnapshot = await getDocs("Road");
  querySnapshot.forEach((doc) => {
    const data = doc.data();
    totalDB2[data.name] = data;
  });
  console.log(totalDB2['road1']); // 正常访问
  // 后续用数据的逻辑都放这
}

// 调用这个异步函数
loadRoadData();

办法3:把数据封装成Promise复用

如果多个地方需要用这份数据,可以把获取逻辑封装成函数,返回Promise:

function getRoadData() {
  return getDocs("Road").then((querySnapshot) => {
    const totalDB2 = {};
    querySnapshot.forEach((doc) => {
      const data = doc.data();
      totalDB2[data.name] = data;
    });
    return totalDB2;
  });
}

// 要用的时候再调用
getRoadData().then((totalDB2) => {
  console.log(totalDB2['road1']);
  // 写业务逻辑
});

提醒

  • 别再用数组存键值对了,对象或者Map才是干这个的,符合JS的规范。
  • 异步请求的结果只能在异步回调(.then()里、await之后)里靠谱地拿到,同步代码抢在异步请求完成前跑,肯定拿不到数据。

内容的提问来源于stack exchange,提问作者노경현

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:55:22