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

React Native配合Firebase使用async/await时执行顺序异常问题

问题原因
  1. Firebase Realtime Database 的 on() 方法是用于注册实时数据监听器的API,返回值为监听器取消函数,不是Promise,因此外层的await不会等待监听器回调执行完成,注册完监听器后就会直接执行后续的console.log('here1')和分支判断逻辑,此时checkExist还未被更新,所以第一次输出here1 false。
  2. 代码中await firebase.database().ref("Tasks").child(snapshot2.key).child(task.taskname)的写法无效,ref()方法返回的是数据库引用对象,并非异步Promise,await对其没有作用。后续的countChild.on("value")同样是监听器注册逻辑,回调会异步执行,不会阻塞外层代码。
  3. 输出中出现多次here1是因为on()注册的监听器会持续接收数据更新事件,每次数据变化都会触发回调,导致重复执行状态更新。
解决方案

如果你的需求是仅单次查询数据完成校验,将所有on()方法替换为返回Promise的once()方法,调整异步逻辑顺序,把后续的分支判断放到所有异步查询完成之后执行:

toggleisModal = async () => {
  const task = this.props.task;
  let checkExist = false;
  // 单次获取Tasks下的所有子节点,用once('value')代替on('child_added')
  const tasksSnapshot = await firebase.database().ref("Tasks").once("value");
  // 遍历所有子节点
  for (const snapshot2 of tasksSnapshot.forEach(childSnap => {
    if (childSnap.exists()) {
      // 单次查询对应taskname的子节点数量
      const snapshot3 = await firebase.database()
        .ref("Tasks")
        .child(childSnap.key)
        .child(task.taskname)
        .once("value");
      if (snapshot3.numChildren() >= 6) {
        checkExist = true;
        console.log("here2 ", checkExist);
        return true; // forEach返回true会终止遍历
      }
    }
  }));
  // 所有查询完成后再执行后续逻辑
  console.log("here1 ", checkExist);
  if (checkExist === true) {
    this.setState({ showTaskVisible: false, checkExist: true });
  } else {
    this.setState({ showTaskVisible: !this.state.showTaskVisible, checkExist: false });
  }
};

如果确实需要使用实时监听的能力,不要把后续分支判断写在监听器注册逻辑的后面,而是把状态更新和分支逻辑全部放到监听器的回调内部执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:54:00