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

useEffect钩子内while循环无法运行,如何实现每7秒获取设备定位?

存在的问题

  • 自定义的sleep函数无效:setTimeout是异步API,调用后会立刻返回不会阻塞主线程,你的sleep函数没有任何等待效果,导致while(true)会瞬间无限循环调用GetLocation.getCurrentPosition,直接占满JS主线程资源,后续的定位回调、UI渲染全部被阻塞,看起来就像循环没有执行。
  • 单线程阻塞问题:JS是单线程执行模型,同步的死循环会一直占用执行栈,所有异步任务(包括定位的then回调、setTimeout回调)都只能在任务队列等待,永远得不到执行机会。
  • 缺少清理逻辑:没有处理组件卸载时的定时任务终止逻辑,会导致内存泄漏、组件卸载后依然继续请求定位的问题。

正确实现方案

采用递归setTimeout实现间隔请求,既能保证两次请求的间隔为7秒,也能避免定位请求超时导致的任务堆叠问题,同时增加卸载清理逻辑:

useEffect(() => {
  let timerId = null;
  let isUnmounted = false; // 标记组件是否卸载,避免卸载后更新state报错

  const getPosition = async () => {
    try {
      const location = await GetLocation.getCurrentPosition({
        enableHighAccuracy: true,
        timeout: 15000,
      });
      if (!isUnmounted) {
        const { latitude, longitude, altitude, accuracy } = location;
        setPosition({ lat: latitude, lon: longitude, alt: altitude, acc: accuracy });
        setLoading(false);
      }
    } catch (err) {
      if (!isUnmounted) alert(err);
    } finally {
      // 无论请求成功失败,都等待7秒后发起下一次请求
      if (!isUnmounted) {
        timerId = setTimeout(getPosition, 7000);
      }
    }
  };

  // 发起第一次定位请求
  getPosition();

  // 组件卸载时清理定时任务
  return () => {
    isUnmounted = true;
    clearTimeout(timerId);
  };
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 10:06:00