使用Image File Resizer批量缩放图片时Promise阻塞UI,需按键恢复
问题分析与解决方案
核心问题拆解
- UI冻结+Promise阻塞:串行处理每张图片时,
resizeFile的Promise仅处理了成功回调,未捕获错误。一旦imageFileResizer内部出错或回调未触发,Promise会一直处于pending状态,导致UI卡住,必须手动触发按键等事件才可能继续执行。 - 回调无法进入:大概率是
imageFileResizer的参数配置有误,或是未处理错误回调,导致成功回调根本没被触发。 - 状态更新不合理:循环内重复调用
setPics和setIsLoading,触发多次组件重渲染,加重UI卡顿。
修复步骤
1. 完善Promise的错误处理
给imageFileResizer添加错误回调,同时在Promise中处理reject,避免Promise一直pending:
const resizeFile = (file) => new Promise((resolve, reject) => { Resizer.imageFileResizer( file, 150, 150, "JPEG", 90, 0, (uri) => { resolve(uri); }, (error) => { // 新增错误回调 reject(error); }, "base64" ); });
2. 并行处理图片,减少UI阻塞
将串行的await改为Promise.all,一次性处理所有图片,避免逐个等待导致的长时间卡顿:
useEffect(() => { const resizeImages = async () => { if (!startEffect.length) return; try { // 并行处理所有图片 const resizedImages = await Promise.all( startEffect.map(file => resizeFile(file)) ); // 一次性更新状态,减少重渲染 setPics(prev => [...prev, ...resizedImages]); } catch (err) { console.error('图片缩放失败:', err); } finally { // 所有处理完成后再关闭加载状态 setIsLoading(false); } }; resizeImages(); }, [startEffect]);
3. 检查imageFileResizer参数正确性
- 尝试将格式参数改为小写(比如
"jpeg"),部分库版本对大小写敏感。 - 确认旋转参数
0符合需求,排除参数异常导致的回调不触发。 - 验证
startEffect中的每个元素都是有效的File对象,无损坏或不支持的格式。
4. 避免不必要的重渲染
原循环内每次setPics都会触发组件更新,改为一次性合并所有结果后再更新,可大幅减少重渲染次数,缓解UI卡顿。
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

