基于Promise的Yup图片批量验证异常:始终返回true
问题分析与修复方案
核心问题
你的验证逻辑存在异步操作与同步代码不匹配的问题,导致验证还没等图片加载完成就提前返回true:
- 数组验证逻辑错误:
Array.filter是同步方法,但图片的onload是异步回调。你在filter里创建图片后立刻执行resolve(wrongImages.length === 0),此时onload还没触发,filter根本没拿到正确判断结果,wrongImages是空数组,直接返回true。 - 单个文件验证的逻辑漏洞:单个文件的
onload里,if判断后没加else,不管尺寸是否符合,最后都会执行resolve(true),导致不符合条件的文件也返回true。 - 数组验证的错误处理:数组里某张图片出错时直接
resolve(false),会中断整个验证流程,应该等所有图片验证完成后统一返回结果。
修正后的验证函数
const validateImageSize = (file, minWidth, minHeight) => { // 抽离单个文件验证逻辑 const validateSingleFile = (f) => { return new Promise((resolve) => { const img = new Image(); img.src = window.URL.createObjectURL(f); img.onerror = () => { window.URL.revokeObjectURL(img.src); resolve(false); // 加载失败视为验证不通过 }; img.onload = () => { window.URL.revokeObjectURL(img.src); const isValid = img.naturalWidth >= minWidth && img.naturalHeight >= minHeight; resolve(isValid); }; }); }; // 处理数组/文件列表 if (Array.isArray(file)) { // 并行验证所有文件,全部通过才返回true return Promise.all(file.map(validateSingleFile)).then(results => { return results.every(isValid => isValid); }); } else { // 单个文件验证 return validateSingleFile(file); } };
Yup Schema 调整
优化空值判断逻辑,确保数组存在且有内容:
validationSchema: Yup.object().shape({ is_delayed: Yup.boolean(), delay_evidence: Yup.array().when('is_delayed', { is: true, then: Yup.array() .min(1, 'Upload at least one picture') .test('required', 'You need to provide a file', (files) => files && files.length > 0) .test('imageSize', 'Image width and height should be at least 200x200', (files) => validateImageSize(files, 200, 200)) }) })
关键说明
- 用
Promise.all并行处理所有文件验证,等所有图片加载判断完成后,用every检查是否全部通过。 - 抽离单个文件验证逻辑,避免重复代码,同时保证逻辑统一。
- 修复了单个文件验证里的
resolve逻辑错误,确保只有尺寸符合才返回true。
内容的提问来源于stack exchange,提问作者Paullo
相关产品推荐
相关产品推荐

