图片上传前Promise校验未完成即存入State的问题修复咨询
问题分析与解决方案
核心问题
你当前的代码有两个关键错误,导致校验未完成就直接存入state:
filter用异步函数无效:Array.filter不会等待异步函数返回结果,它会把所有Promise都视为true,所以lengthTest的长度永远等于profileObjects.length,条件永远满足,直接执行setSelectedImages。- Instagram校验逻辑写错:宽度和比例的判断条件逻辑错误,导致这些校验规则永远不会触发错误提示。
修正后的代码
第一步:修复校验函数的逻辑错误
先修正instagramImageValidation里的条件:
const instagramImageValidation = async (files) => { if (files.length === 0) { console.log("no file") return true; } const extension = ['jpeg']; const fileType = files[0]?.file?.name?.split('.')[1] const fSizeMB = Math.round((files[0]?.file?.size / 1048576)); const { width, height } = await reactImageSize(files[0]?.data_url); console.log("fileType", fileType) console.log("files", files) console.log("fileSize", fSizeMB) console.log("width",width , "height", height) console.log("aspect ratio" , height/width) if (files?.length > 0 && !extension.includes(fileType)) { toast.error('Please upload a valid image (jpeg)', { duration: 5000, position: 'top-center', style: { borderRadius: '10px', background: '#333', color: '#fff', }, id:"validationCheck" }); return false; } else if (files?.length > 0 && fSizeMB >= 8) { toast.error('File size should be less than 8MB', { duration: 5000, position: 'top-center', style: { borderRadius: '10px', background: '#333', color: '#fff', }, id:"validationCheck" }); return false; } // 修正:宽度小于320 或者 大于1440时触发错误 else if (files?.length > 0 && (width < 320 || width > 1440)) { toast.error('Image width should be between 320 to 1440 px', { duration: 5000, position: 'top-center', style: { borderRadius: '10px', background: '#333', color: '#fff', }, id:"validationCheck" }); return false; } // 修正:比例小于0.8 或者 大于1.91时触发错误 else if (files?.length > 0 && ((height/width) < .8 || (height/width) > 1.91)) { toast.error('Aspect ratio should be between .8 to 1.91', { duration: 5000, position: 'top-center', style: { borderRadius: '10px', background: '#333', color: '#fff', }, id:"validationCheck" }); return false; } else { return true } }
第二步:修复图片上传函数的校验逻辑
把filter改成map,收集所有校验结果后检查是否全部通过:
const onSelectedImageList = async (imageList) => { console.log('imageList: ', imageList); console.log("profileObjects-->", profileObjects) // 用map获取所有校验结果的Promise数组 const validationResults = await Promise.all(profileObjects.map(async (o) => { if (o.platformType === "facebook") { return await faceBookImageValidation(imageList) } if (o.platformType === "instagram") { return await instagramImageValidation(imageList) } // 其他平台默认返回true,可按需调整 return true; })) console.log(validationResults, " ", profileObjects) // 检查所有校验是否全部通过 const allPassed = validationResults.every(result => result === true); if (allPassed) { setSelectedImages(imageList); } else { console.log("failed") } };
修正逻辑说明
map配合Promise.all能正确收集所有异步校验的结果,得到一个由true/false组成的数组。every方法会检查数组内每一项是否都是true,只有全部校验通过才会执行setSelectedImages,确保异步校验完成后再更新state。
内容的提问来源于stack exchange,提问作者Sushanth
相关产品推荐
相关产品推荐

