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

如何修复async/await函数需调用四次才返回完整数据的问题

问题分析与解决方案

针对你遇到的fetchAllUsersByLocation函数返回数据不完整、Promise处理异常的问题,以下是具体排查和修复步骤:

1. 修正异步函数的错误处理与数据映射

当前函数在捕获错误后未明确返回值,且数据映射逻辑可优化,避免因异常导致返回undefined:

export const fetchAllUsersByLocation = async () => {
  console.log("called");
  const givenLocation = {
    latitude: 33.1781735,
    longitude: -117.334903,
  };

  const geohash = GeoHash.encodeGeoHash(
    givenLocation.latitude,
    givenLocation.longitude,
    9
  );

  const boundingBox = getGeoHashBoundingBox(
    givenLocation.latitude,
    givenLocation.longitude,
    20
  );

  try {
    const db = getFirestore();
    const usersRef = collection(db, "users");
    const filteredUsersQuery = query(
      usersRef,
      where("coordinates", ">=", boundingBox.min),
      where("coordinates", "<=", boundingBox.max)
    );

    const querySnapshot = await getDocs(filteredUsersQuery);
    // 直接用map转换文档数据,同时可选携带文档ID
    const filteredUsers = querySnapshot.docs.map(doc => ({
      id: doc.id,
      ...doc.data()
    }));
    console.log(filteredUsers);
    return filteredUsers;
  } catch (e) {
    console.error("Fetch users error:", e);
    // 抛出错误让调用方处理,或返回空数组
    throw e;
    // return [];
  }
};

2. 组件中正确处理异步调用与状态管理

在React Native组件中调用时,必须确保等待Promise完成,并处理竞态条件(避免组件卸载后更新状态):

import { useState, useEffect } from 'react';
import { Text, View, FlatList } from 'react-native';
import { fetchAllUsersByLocation } from './your-file-path';

const UserList = () => {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let isMounted = true;

    const loadUsers = async () => {
      try {
        const userData = await fetchAllUsersByLocation();
        if (isMounted) {
          setUsers(userData);
          setLoading(false);
        }
      } catch (err) {
        if (isMounted) {
          setError(err.message);
          setLoading(false);
        }
      }
    };

    loadUsers();

    // 组件卸载时标记为已销毁
    return () => {
      isMounted = false;
    };
  }, []);

  if (loading) return <Text>加载中...</Text>;
  if (error) return <Text>错误:{error}</Text>;

  return (
    <FlatList
      data={users}
      renderItem={({ item }) => (
        <View style={{ padding: 10 }}>
          <Text>昵称:{item.displayName}</Text>
          <Text>年龄:{item.age}</Text>
          <Text>坐标:{item.coordinates}</Text>
        </View>
      )}
      keyExtractor={item => item.id}
    />
  );
};

export default UserList;

3. 修复Geohash边界计算的关键错误

原代码中Math.cos(latitude)使用角度值,但JavaScript的cos函数需要弧度值,导致边界框计算错误,这是查询结果不稳定的核心原因之一:

function getGeoHashBoundingBox(latitude, longitude, radius, precision = 9) {
  const latDiff = radius / 69; // 1纬度≈69英里
  // 转换纬度为弧度后计算经度差
  const lonDiff = Math.abs(radius / (69 * Math.cos(latitude * Math.PI / 180)));

  const minLat = latitude - latDiff;
  const maxLat = latitude + latDiff;
  const minLon = longitude - lonDiff;
  const maxLon = longitude + lonDiff;

  // 统一使用9位精度编码Geohash
  const minGeoHash = GeoHash.encodeGeoHash(minLat, minLon, precision);
  const maxGeoHash = GeoHash.encodeGeoHash(maxLat, maxLon, precision);

  return {
    min: minGeoHash,
    max: maxGeoHash,
  };
}

4. 排查数据完整性与缓存问题

  • 检查Firestore文档:确认users集合中所有文档都包含displayName、age等字段,部分文档缺失字段会导致返回数据不完整。
  • 清除缓存:React Native或Firestore SDK的离线缓存可能返回旧数据,可尝试重启Metro服务、模拟器/真机,或临时禁用Firestore持久化缓存排查:
    // 初始化Firestore时临时禁用持久化
    const db = getFirestore(app, { persistence: false });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:30:13