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

为什么通过循环向Firebase插入数据时实际插入数量随机?

问题原因
  • 核心原因:Key重复覆盖:Date.now()返回值的精度为毫秒级,JavaScript同步for循环的执行速度远快于1毫秒,会出现多次循环调用Date.now()得到完全相同时间戳的情况。你用时间戳作为History下的子节点Key,后续同Key的set操作会直接覆盖之前写入的同节点数据,最终只会保留每个毫秒区间内最后一次的写入结果,自然出现实际插入数量随机、少于预期的情况。
  • 次要原因:异步操作未做等待管理:Firebase的set()是异步网络请求,你没有对这些异步操作做完成状态监听,如果测试过程中页面提前卸载、或者环境触发请求节流,也可能出现部分请求未正常发出的情况,该场景下的问题90%以上是Key重复导致的。
修复方案
  1. 调整节点Key生成规则,避免重复:可以把循环变量i拼到Key中,或者直接用Firebase SDK自带的push()方法生成全局唯一的递增Key,示例修改后的代码如下:
function sendMessage(times){
    const writePromises = []; // 收集所有异步写入的Promise,方便后续统计耗时
    for(let i = 0; i < times; i++){
        console.log(i);
        let messageObj = {
           user: "testUser" + i,
           message: "message" + i
        };
        // 方案1:拼接i避免Key重复
        const ref = firebase.database().ref("History/" + Date.now() + "_" + i);
        // 方案2:用push生成唯一Key,更推荐
        // const ref = firebase.database().ref("History").push();
        writePromises.push(ref.set(messageObj));
    }
    // 所有写入完成后再统计耗时
    Promise.all(writePromises).then(() => {
        console.log("所有数据写入完成,可统计结束时间");
    })
}

window.onload = function () {
    sendMessage(50);
}
  1. 如果需要准确统计插入耗时,不要从循环开始就计时,要等Promise.all返回后再计算结束时间,否则统计的只是同步循环的执行耗时,不是真正的网络写入完成耗时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:45:07