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

Expo React Native打车应用Google Directions API请求量过高优化咨询

React Native打车应用Google Directions API请求过量优化方案

核心问题根源

你的代码触发过量请求的原因有两点:

  • 监听lastLocation的useEffect会在司机位置每次更新时直接调用fitMap触发API请求
  • 20秒一次的定时器也会在位置变化时重复调用fitMap请求路线
    同时每次请求都会覆盖liveRouteCoords,导致旧轨迹被清除。

优化方案

优化逻辑核心为:仅在订单状态切换的第一时间请求路线,后续位置更新仅调整地图视口不触发接口调用,可按需设置长间隔刷新到达时间,避免配额浪费。

第一步:新增辅助状态

// 存储当前行程的固定目标点
const [currentDest, setCurrentDest] = useState(null);
// 标记当前阶段是否已经请求过路线
const [routeFetched, setRouteFetched] = useState(false);

第二步:修改位置监听useEffect

useEffect(() => {
  // 订单状态变为接受时,仅首次请求到乘客的路线
  if (curBooking?.status == 'ACCEPTED' && !routeFetched && lastLocation) {
    const dest = {
      lat: curBooking.pickup.lat,
      lng: curBooking.pickup.lng
    };
    setCurrentDest(dest);
    fitMap(lastLocation, dest, true);
    setRouteFetched(true);
    setlastCoords(lastLocation);
    return;
  }

  // 司机到达上车点时重置路线状态
  if (curBooking?.status == 'ARRIVED') {
    setlastCoords(null);
    setRouteFetched(false);
    setCurrentDest(null);
    setTimeout(() => {
      mapRef.current.fitToCoordinates([{
        latitude: curBooking.pickup.lat,
        longitude: curBooking.pickup.lng
      }, {
        latitude: curBooking.drop.lat,
        longitude: curBooking.drop.lng
      }], {
        edgePadding: { top: 40, right: 40, bottom: 40, left: 40 },
        animated: true,
      })
    }, 1000);
    return;
  }

  // 订单开始行程时,仅首次请求到目的地的路线
  if (curBooking?.status == 'STARTED' && !routeFetched && lastLocation) {
    const dest = {
      lat: curBooking.drop.lat,
      lng: curBooking.drop.lng
    };
    setCurrentDest(dest);
    fitMap(lastLocation, dest, true);
    setRouteFetched(true);
    setlastCoords(lastLocation);
    return;
  }

  // 后续位置更新仅调整视口,不请求路线
  if (lastLocation && currentDest && routeFetched) {
    mapRef.current.fitToCoordinates([{
      latitude: lastLocation.lat,
      longitude: lastLocation.lng
    }, {
      latitude: currentDest.lat,
      longitude: currentDest.lng
    }], {
      edgePadding: { top: 40, right: 40, bottom: 40, left: 40 },
      animated: true,
    })
    setlastCoords(lastLocation);
  }

  // 乘客端到达后的视口调整逻辑保持不变
  if (lastLocation && curBooking?.status == 'REACHED' && role == 'rider') {
    setTimeout(() => {
      mapRef.current.fitToCoordinates([{
        latitude: curBooking.pickup.lat,
        longitude: curBooking.pickup.lng
      }, {
        latitude: lastLocation.lat,
        longitude: lastLocation.lng
      }], {
        edgePadding: { top: 40, right: 40, bottom: 40, left: 40 },
        animated: true,
      })
    }, 1000);
  }
}, [lastLocation, curBooking])

第三步:修改定时器逻辑

useEffect(() => {
  // 可将间隔拉长到2分钟,仅用于更新到达时间,不需要可以直接删除定时器
  const interval = setInterval(() => {
    if (pageActive.current && curBooking && lastLocation && currentDest && routeFetched) {
      fitMap(lastLocation, currentDest, true);
    }
  }, 120000);
  // 组件卸载时清理定时器避免内存泄漏
  return () => clearInterval(interval);
}, [currentDest, routeFetched]);

第四步:改造fitMap函数

// 新增fetchRoute参数控制是否触发接口请求
const fitMap = (point1, point2, fetchRoute = false) => {
  if (fetchRoute) {
    let startLoc = `"${point1.lat},${point1.lng}"`;
    let destLoc = `"${point2.lat},${point2.lng}"`;
    getRouteDetails(Platform.OS, startLoc, destLoc).then((details) => {
      setArrivalTime(details.duration ? parseFloat(details.duration / 60).toFixed(0) : 0);
      let points = Polyline.decode(details.polylinePoints);
      let coords = points.map((point) => ({
        latitude: point[0],
        longitude: point[1]
      }))
      // 若要保留历史行驶轨迹,改为 setLiveRouteCoords(prev => [...prev, ...coords])
      setLiveRouteCoords(coords);
      // 调整地图视口
      mapRef.current.fitToCoordinates([{
        latitude: point1.lat,
        longitude: point1.lng
      }, {
        latitude: point2.lat,
        longitude: point2.lng
      }], {
        edgePadding: { top: 40, right: 40, bottom: 40, left: 40 },
        animated: true,
      })
    });
  } else {
    // 不需要请求接口时仅调整视口
    mapRef.current.fitToCoordinates([{
      latitude: point1.lat,
      longitude: point1.lng
    }, {
      latitude: point2.lat,
      longitude: point2.lng
    }], {
      edgePadding: { top: 40, right: 40, bottom: 40, left: 40 },
      animated: true,
    })
  }
}

效果说明

调整后请求量至少减少90%,如果不需要动态更新到达时间可直接删除定时器,全程仅请求2次路线(去上车点、去目的地)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:39:00