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

React Native中useEffect内Promise.race未解析的渐进式图片加载问题

渐进式图片加载器Promise.race未解析问题修复

你的代码存在几个关键问题,直接导致了Promise.race后续逻辑不执行,以下是排查和修复方案:

1. 语法错误:if语句未闭合

handleRace函数中的if块漏掉了闭合的},JavaScript引擎解析失败,整个函数无法正常执行,自然不会输出后续日志。修复后:

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

2. 缺少错误捕获逻辑

Promise.race中任意一个Promise发生reject时,整个race会直接抛出错误,而你的代码没有添加错误捕获,错误会被静默(或触发未捕获Promise rejection),导致代码中断。给handleRace加上错误处理:

async function handleRace() {
  try {
    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');
    }
  } catch (err) {
    console.error('加载流程出错:', err);
    // 可在此添加UI错误提示逻辑
  }
}

3. 状态变量管理问题

isCacheChecked和cacheHit如果是普通变量,组件重新渲染时会被重置,且async函数会捕获变量的旧值,导致逻辑判断错误。改用React的useState管理这些状态:

const [cacheHit, setCacheHit] = useState(false);
const [isCacheChecked, setIsCacheChecked] = useState(false);

// 在checkCache中更新状态
async function checkCache() {
  // 缓存检查逻辑,示例使用Cache API
  const cache = await caches.open('image-cache');
  const cachedResponse = await cache.match(imageSource);
  if (cachedResponse) {
    const blob = await cachedResponse.blob();
    setImageSource(URL.createObjectURL(blob));
    setCacheHit(true);
  }
  setIsCacheChecked(true);
  console.log('缓存检查完成');
  return !!cachedResponse;
}

4. 函数定义语法错误

你贴出的代码中三个async函数使用了async function checkCache();这种带分号的错误写法,函数声明不能带分号,改为标准定义形式:

async function checkCache() {
  // 具体实现逻辑
}

额外优化点

  • 缓存未命中时无需重复调用downloadAndSetSmallAndMediumImages,Promise.race已经在并行执行该函数,重复调用会导致冗余下载。
  • 在useEffect的清理函数中,revoke通过URL.createObjectURL创建的blob链接,避免内存泄漏:
return () => {
  if (imageSource?.startsWith('blob:')) {
    URL.revokeObjectURL(imageSource);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:23:27