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

如何确保Firebase数据库调用完成后再使用统计数据?

解决Firebase异步请求未完成就渲染统计数据的问题

问题核心

你遇到的问题是异步操作未等待完成就执行后续逻辑:

  1. 第一个then中,遍历userMatches发起的get(ref(database, \matches/${v}`))是异步请求,但forEach不会等待这些请求完成,就直接执行后续代码并进入下一个then。此时userMatches里还是存储的match ID,未被替换为完整的match对象,导致map(v => v.category)得到undefined`。
  2. 后续then链没有等待前置异步操作全部完成,依赖异步数据的逻辑自然出错。

修正后的代码

async function addStats() {
    let userMatches, wins, losses, ties;

    // 获取用户的match ID列表
    const matchesSnapshot = await get(ref(database, `users/${user.uid}/matches`));
    userMatches = Object.values(matchesSnapshot.val());

    // 并行获取所有match的详细数据,等待全部完成
    const matchPromises = userMatches.map(matchId => get(ref(database, `matches/${matchId}`)));
    const matchSnapshots = await Promise.all(matchPromises);
    userMatches = matchSnapshots.map(snap => snap.val());

    // 渲染比赛数量统计
    addStat('matchesPlayed', userMatches.length);

    // 计算并渲染最喜爱的比赛类别
    const categories = userMatches.map(v => v.category);
    addStat('favCategory', getMode(categories));

    // 并行获取胜负平数据,提升效率
    const [winsSnapshot, lossesSnapshot, tiesSnapshot] = await Promise.all([
        get(ref(database, `users/${user.uid}/wins`)),
        get(ref(database, `users/${user.uid}/losses`)),
        get(ref(database, `users/${user.uid}/tied`))
    ]);
    wins = winsSnapshot.exists() ? winsSnapshot.val() : 0;
    losses = lossesSnapshot.exists() ? lossesSnapshot.val() : 0;
    ties = tiesSnapshot.exists() ? tiesSnapshot.val() : 0;

    // 渲染胜负平统计
    addStat('wlt', [wins, losses, ties].join('/'));
}

关键修改说明

  • 改用async/await替代嵌套then,逻辑更直观,便于明确等待异步操作完成。
  • 用Promise.all并行处理多异步请求:
    • 所有match详情请求先打包成Promise数组,等待全部完成后再更新userMatches,确保后续逻辑拿到的是完整的match对象。
    • 胜负平的三个请求并行发起,减少总等待时间。
  • 移除冗余的then链嵌套,每一步都明确等待依赖的异步操作完成后再执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 02:58:30