You need to enable JavaScript to run this app. React Native渔船日历功能map处理Firebase异步返回空对象问题
优惠活动
大模型
产品
解决方案
定价
更多

React Native渔船日历功能map处理Firebase异步返回空对象问题

核心问题根源

你现在执行后拿到空schedules的原因非常明确,两个点:

  • 给selectedFishingMethods.map()套await完全起不到等待作用:map遍历返回的是普通数组,不是Promise集合,await根本不会等数组里的异步回调跑完,会直接同步执行后面的打印和状态更新逻辑
  • Firebase的.on('value')是持续事件监听接口,不是可等待的请求Promise:调用后只会注册一个数据变更的回调,不会阻塞当前执行流等数据库返回,你执行状态更新的时候,数据库的回调还没触发,自然拿不到填充好的schedules
可落地的修正方案

调整逻辑

  • 如果日历初始化只需要拉一次全量排期数据,把持续监听的.on('value')换成一次性拉取的once('value'),这个方法会返回标准Promise,可以被await等待
  • 用Promise.all聚合所有选中钓鱼方式对应的拉取任务,等所有任务都拿到数据、完成schedules聚合后,再触发状态更新

修正后的业务代码

const getTourSchedules = async () => {
  const schedules = {};
  // 为每个选中的钓鱼方式创建独立的拉取任务
  const fetchTasks = selectedFishingMethods.map(async (item) => {
    const dbRef = `schedules/${item}`;
    // 一次性获取指定钓鱼方式下的所有排期数据
    const snapShot = await Firebase.database().ref(dbRef).once('value');
    if (!snapShot.exists()) return;
    // 遍历排期条目,按日期聚合
    snapShot.forEach((docs) => {
      const tour = docs.val().contents;
      const schedule = {
        endTime: tour.endTime,
        startTime: tour.startTime,
        shipName: tour.shipName,
      }
      if (!schedules[tour.date]) {
        schedules[tour.date] = [schedule];
      } else {
        schedules[tour.date].push(schedule);
      }
    })
  });
  // 等待所有钓鱼方式的排期拉取、聚合全部完成
  await Promise.all(fetchTasks);
  // 所有数据处理完再更新状态
  setTours({ ...schedules });
};

适配实时场景的说明

如果后续业务需要实时同步渔船预约的状态变化,不需要把.on('value')换成once,但要删掉map循环结束后立刻执行的setTours逻辑,改成在每次监听回调触发、完成schedules聚合后,同步执行setTours,这样数据变化时界面会同步刷新,不会出现空对象的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.10 12:54:09