如何正确处理嵌套Promise拒绝?实现readerProcess随imageProcess拒而拒
解决readerProcess无法随imageProcess一起拒绝的问题
我明白你的困扰——你现在的核心问题是:readerProcess的Promise在reader.onload里直接resolve了imageProcess的Promise,导致即使imageProcess后续拒绝,readerProcess的状态已经被固定为resolved,没法再触发reject。
问题根源
Promise的状态是不可逆的:一旦调用了resolve(),Promise就进入resolved状态,后续再调用reject()完全不会生效。你之前的写法里,resolve(imageProcess(reader))相当于直接把imageProcess的Promise作为readerProcess的resolve值,不管imageProcess成功还是失败,readerProcess已经被标记为resolved了,所以你在imageProcess的catch里写的reject根本起不了作用。
修正方案
我们需要调整reader.onload里的逻辑:不要直接resolveimageProcess的Promise,而是等待imageProcess执行完成,根据它的结果来决定readerProcess是resolve还是reject。同时别忘了加上reader自身的错误处理,避免文件读取失败时Promise一直pending。
修正后的完整代码如下:
const target = e.target.name; readerProcess(file) .then(res => {console.log('reader result', res)}) .catch(err => {console.log('error', err)}); // 现在能正确捕获所有错误了 const readerProcess = (file) => { return new Promise((resolve, reject) => { let reader = new FileReader(); if(file) reader.readAsDataURL(file); reader.onload = () => { // 先等待imageProcess的结果,再决定readerProcess的状态 imageProcess(reader) .then(image => { // imageProcess成功,返回需要的数据 resolve({ data: reader.result, width: image.width, height: image.height }); }) .catch(err => { // imageProcess失败,直接reject readerProcess reject(err); }); }; // 处理文件读取本身的错误(比如权限问题、文件损坏) reader.onerror = () => { reject(reader.error); }; }); }; const imageProcess = (reader) => { return new Promise((resolve, reject) => { let img = new Image() img.onload = () => resolve(img) img.onerror = reject; // 无效图片时触发reject img.src = reader.result; }); };
为什么这样可行?
- 当
reader加载完成后,我们先调用imageProcess,而不是直接把它传给resolve - 如果
imageProcess成功(有效图片),我们就调用resolve()把结果返回给readerProcess的调用者 - 如果
imageProcess失败(无效图片),我们直接调用reject(),让readerProcess进入rejected状态,这样外层的catch就能捕获到错误 - 新增的
reader.onerror处理了文件读取阶段的错误,避免Promise一直处于pending状态
现在你再测试无效图片的情况,readerProcess会正确触发catch回调,满足你的需求啦!
内容的提问来源于stack exchange,提问作者Md. Jahidul Islam
相关产品推荐
相关产品推荐

