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

VueJS调用Firestore时异步代码返回空数组如何解决

问题背景

开发环境

  • 数据库:Firestore
  • 前端框架:VueJS

开发目标

  1. 读取players集合中所有可用足球运动员的列表,每名运动员对应集合内的独立文档
  2. 获取所有上述运动员对应的全部赛事统计数据
  3. 按球员维度聚合,统计每名球员所有参赛场次的累计数据
故障现象
  • 页面初始化执行逻辑时,this.aggregatedPlayerStats返回空数组
  • 手动通过按钮触发aggregatePlayerStats()方法时,聚合功能可正常运行,初步判断故障和异步代码执行时序有关
原始问题代码
export default {
  name: "AggregatedAllTimeStats",
  data() {
    return {
      allPlayers: [],
      allStats: [],
      aggregatedPlayerStats: []
    };
  },
  async created() {
    await this.getAllPlayers();
    await this.getAllStats();
    this.aggregatePlayerStats();

  },
  methods: {
    async getAllPlayers() {
      return db.collection("players").get().then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          this.allPlayers.push({
            playerid: doc.id,
            name: doc.data().name,
            playerstatus: doc.data().playerstatus
          })
        })
      })
    },
    getAllStats() {
      this.allPlayers.forEach((player) => {
        return db.collection("playerstatsformatch").where("playerid", "==", player.playerid).get().then((querySnapshot) => {
          querySnapshot.forEach((doc) => {
            this.allStats.push(doc.data())
          })
        })
      })
    },
    aggregatePlayerStats() {
      const aggregatedResults = Object.values(
        this.allStats.reduce((a, c) => {
          if (!a[c.playerid]) {
            a[c.playerid] = {
              goals: c.goals,
              name: c.name,
              assists: c.assists

            };
          } else {
            a[c.playerid].goals += c.goals;

          }
          return a;
        }, {})
      );
      this.aggregatedPlayerStats = aggregatedResults
      console.log(this.aggregatedPlayerStats)
    }
  },
};
故障根因

故障点在getAllStats()方法的异步逻辑处理错误:

  1. 方法未声明为async,内部使用forEach遍历球员列表发起Firestore查询时,forEach本身不会等待内部异步请求执行完成,方法会在所有查询刚发起时就同步返回
  2. created钩子中虽然写了await this.getAllStats(),但getAllStats没有返回可等待的有效Promise,await实际没有阻塞执行,会立刻运行后续的aggregatePlayerStats()方法。此时所有赛事统计数据的查询还没返回结果,this.allStats是空数组,最终聚合结果自然为空。
修复方案

修改getAllStats()方法,使用Promise.all等待所有球员的统计数据查询全部完成后再返回,确保执行聚合逻辑时所有统计数据已经写入this.allStats。
修复后的完整代码:

export default {
  name: "AggregatedAllTimeStats",
  data() {
    return {
      allPlayers: [],
      allStats: [],
      aggregatedPlayerStats: []
    };
  },
  async created() {
    await this.getAllPlayers();
    await this.getAllStats();
    this.aggregatePlayerStats();
  },
  methods: {
    async getAllPlayers() {
      const querySnapshot = await db.collection("players").get();
      querySnapshot.forEach((doc) => {
        this.allPlayers.push({
          playerid: doc.id,
          name: doc.data().name,
          playerstatus: doc.data().playerstatus
        })
      })
    },
    async getAllStats() {
      // 收集所有球员的统计数据查询Promise
      const statQueries = this.allPlayers.map(player => {
        return db.collection("playerstatsformatch")
          .where("playerid", "==", player.playerid)
          .get()
      })
      // 等待所有查询执行完成
      const allQuerySnapshots = await Promise.all(statQueries);
      // 统一写入所有统计数据
      allQuerySnapshots.forEach(querySnapshot => {
        querySnapshot.forEach(doc => {
          this.allStats.push(doc.data())
        })
      })
    },
    aggregatePlayerStats() {
      const aggregatedResults = Object.values(
        this.allStats.reduce((a, c) => {
          if (!a[c.playerid]) {
            a[c.playerid] = {
              goals: c.goals,
              name: c.name,
              assists: c.assists
            };
          } else {
            a[c.playerid].goals += c.goals;
            a[c.playerid].assists += c.assists;
          }
          return a;
        }, {})
      );
      this.aggregatedPlayerStats = aggregatedResults
      console.log(this.aggregatedPlayerStats)
    }
  },
};

额外修复点:原聚合逻辑只累加了进球数,漏了助攻数的累加,修复代码中已补充该逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:15:30