React Native 为什么我的回避在10次或15次之后就停止了?

z4bn682m  于 2022-12-14  发布在  React
关注(0)|答案(1)|浏览(137)

我做了一个递归循环,在没有停止标准的情况下,我认为这不重要。我没有在循环中创建任何变量,我只是不明白它为什么会停止:

async function locagetter() {
  return await Location.getCurrentPositionAsync({enableHighAccuracy: true});
}

async function calcdist(val) {
  console.log("hoi");
    val = await locagetter();
    await SetDistance(getPreciseDistance(
      {latitude: 51.493280, longitude: 4.294605 },
      {latitude: val.coords.latitude, longitude: val.coords.longitude}));
      calcdist(val);
}

我尝试了很多也承诺,但我认为它应该工作,我只是需要一个持续的位置刷新。

j5fpnvbx

j5fpnvbx1#

如果你需要一个连续的刷新,那么为什么不使用一个间隔呢?到目前为止,你的递归没有中断条件,所以当组件卸载时它可能仍然运行(我不确定这一点,所以不要引用我的话),而使用间隔,你可以在卸载时开始停止它:

const intervalId = useRef()
const startCoordinate = {latitude: 51.493280, longitude: 4.294605 }
const calcLocationDist = async (coordinate=startCoordinate)=>{
  let currentCoordinate = await Location.getCurrentPositionAsync({
    enableHighAccuracy: true
  });
  SetDistance(getPreciseDistance(coordinate,currentCoordinate)
}
useEffect(()=>{
  intervalId.current = setInterval(()=>{
    calcLocationDist();
  },1000)
  // for component unmounts
  return ()=>{
    clearInterval(intervalId.current)
  }
},[])

你可以更进一步,创建一个useCurrentLocation钩子,这样你就可以做更多的事情,而不会使使用它的组件变得混乱:

const defaultConfig = {
  // interval updates in seconds
  updateInterval=10,
}
export default function useCurrentLocation({onUpdate, onError,updateInterval}=defaultConfig){
  // track errors
  const [error, setError] = useState(null);
  const [value, setValue] = useState({});
  // toggle the interval on and off
  const [shouldUpdate, setShouldUpdate] = useState(true);
  const intervalId = useRef()
  const update = async ()=>{
    try{
      let loc = await Location.getCurrentPositionAsync({
        enableHighAccuracy: true
      });
      setValue(loc);
      onUpdate?.(loc);
    } catch(err){
      setError(err)
      onError?.(setShouldUpdate,error)
    }
  }
  useEffect(()=>{
    if(shouldUpdate){
      intervalId.current = setInterval(()=>{
        update()
      },updateInterval*1000)
    }
    else 
      clearInterval(intervalId.current)
    }
    return ()=>{
      clearInterval(intervalId.current)
    }
  },[shouldUpdate])
  return {
    value,
    error,
    shouldUpdate:setShouldUpdate
  }   
}

然后在使用该位置的组件中:

const startCoordinate = {latitude: 51.493280, longitude: 4.294605 };
const [permissionStatus, requestPermission] = Location.useForegroundPermissions();

const location = useCurrentLocation({
  updateInterval:5,
  onUpdate:newLocation=>{
   SetDistance(getPreciseDist(startCoordinate,newLocation))
  },
  onError:(error,shouldUpdate)=>{
    console.log(error)
    // stop interval
    shouldUpdate(false)
  }
});
// location.value is current location
console.log(location.value)
// location.error is last error 
console.log(location.error)
// location.shouldUpdate is a function that will accept a boolean
// that will turn the interval on or off
useEffect(()=>{
  // if permission is granted turn interval on
  if(permissionStatus?.granted)
    location.shouldUpdate(true)
  else{
   // turn interval off
   location.shouldUpdate(false)
   // if permission can be request again attempt to do so
   if(permissionStatus.canAskAgain)
     requestPermission()
  }
},[permissionStatus])

相关问题