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

如何无需setTimeout等待Firebase实时数据库循环查询结果

问题描述

尝试从成员列表获取每个成员的详细数据,但总是返回undefined,目前用setTimeout等待数据加载,希望去掉setTimeout,让结果等所有循环查询完成后再返回,现有代码如下:

database().ref(`/group/${groupid}`)
    .on("value", snapshot => {
      let data_1 = snapshot.val();
      let members = '';
      let i = 0;
      for(let memberid in data_1) {
        i++;
        database().ref(`/members/${memberid}`)
        .once("value", snapshot => {
          let data_2 = snapshot.val();
          members += '"'+memberid+'":{"uid":"'+data_2.uid+'","name":"'+data_2.name+'","avatar":"'+data_2.avatar+'"},';
        }) 
      } 
      let duration = parseInt(i)*125;
        setTimeout(() => {    
          let resmembers = '{'+members.slice(0, -1)+'}'; 
          let membersobj = JSON.parse(resmembers);
          return membersobj;
        },parseInt(duration))
      })
解决方案

核心问题是循环里的once是异步操作,不会阻塞循环,字符串拼接的方式赶不上异步请求的速度,只能靠猜延迟的setTimeout凑数。改用Promise和Promise.all统一等待所有异步请求完成即可:

  1. 把每个成员的查询包装成Promise
  2. 收集所有Promise到数组,用Promise.all等待全部完成
  3. 处理返回结果,直接构建最终的成员对象

修改后的代码如下:

database().ref(`/group/${groupid}`)
  .on("value", async snapshot => {
    const data_1 = snapshot.val();
    // 收集所有成员查询的Promise
    const memberPromises = [];
    for (const memberid in data_1) {
      const promise = new Promise((resolve) => {
        database().ref(`/members/${memberid}`)
          .once("value", memberSnapshot => {
            const data_2 = memberSnapshot.val();
            // 直接返回结构化的成员数据,避免手动拼接JSON字符串
            resolve({ [memberid]: {
              uid: data_2.uid,
              name: data_2.name,
              avatar: data_2.avatar
            }});
          });
      });
      memberPromises.push(promise);
    }

    // 等待所有查询完成
    const memberResults = await Promise.all(memberPromises);
    // 合并所有结果为一个对象
    const membersobj = Object.assign({}, ...memberResults);
    
    // 此处可直接使用membersobj,无需setTimeout
    console.log(membersobj);
    // 若需外部使用该数据,可调用自定义处理函数
    // handleMembersData(membersobj);
  })

补充说明:

  • 用async/await简化异步代码逻辑,可读性更强
  • 直接构建对象而非拼接JSON字符串,减少语法错误概率
  • Promise.all会并行等待所有请求完成,效率高于逐个等待
  • 注意on回调本身是异步的,内部return无法将结果返回至外部,需通过调用处理函数传递数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 13:27:20