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