【问题标题】:why does my recussion stop after 10 or 15 times?为什么我的回溯在 10 或 15 次后停止?
【发布时间】:2022-12-18 03:47:53
【问题描述】:

我做了一个递归循环,目前没有停止的 criterium 总线,我认为这不重要。我没有在循环中创建任何变量,我只是不明白为什么它会停止:

 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);
}

我也尝试过很多承诺,但我认为它应该有效,我只需要持续刷新位置。

【问题讨论】:

  • 最后一个 locagetter() promise 是否解决了或者挂起了吗?
  • 它最多工作 20 次然后就挂起
  • 是api调用吗?您拥有 API 吗?有速率限制吗?如果它是您不拥有的 API,是否有速率限制?它是否会因错误而解决?

标签: reactjs react-native asynchronous recursion async-await


【解决方案1】:

如果您需要连续刷新,那么为什么不使用间隔呢?截至目前,您的递归没有中断条件,因此当组件卸载时它可能仍会运行(我对此不确定,所以不要引用我的话),您可以在间隔期间开始在卸载时停止它:


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])

【讨论】:

  • 权限请求应该在挂钩中,但我想证明您可以在挂钩之外打开和关闭间隔更新
猜你喜欢
  • 2019-01-10
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 2021-07-15
  • 2017-11-12
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多