Promise.race 未在 React Native 移动应用程序的 useEffect 函数中解析

问题描述 投票:0回答:1

我正在设置一个渐进式图像加载器(下载图像并用相同图像替换图像以提高质量)。首先,我进行缓存检查以查看图像是否已缓存。但是,在加载时,我会下载较低质量的图像,以防我要加载的图像没有缓存命中。代码如下所示:

useEffect(() => {
  // checks if image exists in cache, sets it to imageSource if it does
  async function checkCache(); 

  // downloads 2 lower quality images and sets them to imageSource when their download finishes
  async function downloadAndSetSmallAndMediumImages(); 

  // downloads the highest quality image and stores it in cache
  async function handleFinalBigImageDownloadAndSet();

  async function handleRace() {
    const raceResult = await Promise.race([checkCache(), downloadAndSetSmallAndMediumImages()]);
    console.log('here', raceResult);
    if (isCacheChecked && !cacheHit) {
      console.log('cache miss');
      await downloadAndSetSmallAndMediumImages();
      await handleFinalBigImageDownloadAndSet();
    else {
      console.log('cache hit');
    }
  }

  handleRace();
  return () => {};
}, [imageSource]);

在handleRace()函数中,控制台日志永远不会出现——看起来Promise.race()没有解析。我在 checkCache() 函数的末尾设置了一些 console.log() ,这些实际上记录在控制台中。下一行执行应该是 Promise.race() 解析以及随后的结果记录。因此,在应用程序的 UI 上,加载指示器无限期地保持(因为 imageSource 需要由这些函数设置),直到我刷新页面,然后突然图像可见,但 Promise.race 之后的 console.log() () 仍然没有显示。

javascript typescript react-native react-hooks react-native-flatlist
1个回答
0
投票

您需要使用 React 生命周期。

react

useEffect
不处理异步回调,所以你应该使用不带
await
的promise,只使用
.then
useSetate
,例如:

// outside the component context if it's possible
async function checkCache(); 

async function downloadAndSetSmallAndMediumImages(); 
...
  const [raceResult, setRaceResult] = useState(false):
  useEffect(() => {
  
    Promise.race([checkCache(), downloadAndSetSmallAndMediumImages()]).then(setRaceResult);

  }, [imageSource])

  useEffect(() => {
    console.log('here', raceResult);
    if (isCacheChecked && !cacheHit) {
      console.log('cache miss');
      // Use fire and forget if it's possible and apply the same approach with the useState in case of require to handle an action once the promise finish
      downloadAndSetSmallAndMediumImages().then(() => handleFinalBigImageDownloadAndSet());
    else {
      console.log('cache hit');
    }
  }, [raceResult, isCacheChecked, cacheHit])
© www.soinside.com 2019 - 2024. All rights reserved.