Async/Await中Catch块二次抛错的处理与语法选型探讨
async/await 中 catch 块内部拒绝的处理方案
在使用 async/await 时,用 try/catch 处理 Promise 拒绝已经成了行业标准,但如果 catch 块内部存在可能触发拒绝的异步操作,该怎么处理就成了问题。
错误的写法(无法运行)
有人尝试用连续的 catch 块来处理,但这在 JavaScript 里是无效的——try 和 catch 是成对出现的,多个 catch 会直接导致语法错误:
// 无法运行! try { await Promise.reject() } catch (e) { console.log('caught rejection') await Promise.reject() } catch (e) { console.log('caught rejection again') }
可行但可读性差的嵌套写法
最直接的解决方式是在 catch 块里再套一层 try/catch,虽然能正常运行,但逻辑嵌套多了之后,代码会变得臃肿、可读性下降:
try { await Promise.reject() } catch (e) { console.log('caught rejection') try { await Promise.reject() } catch(e2) { console.log('caught rejection again') } }
传统链式写法的替代
这时有人会想到回到传统的 .then()/.catch() 链式写法,这种方式不需要嵌套,逻辑看起来更连贯:
Promise.reject() .catch(() => { console.log('caught rejection') return Promise.reject() }).catch(() => { console.log('caught rejection again') })
要不要放弃 try/catch?当然不用
这种场景完全不能成为反对 try/catch 的依据——try/catch 在同步+异步混合的逻辑中,可读性远优于链式写法,更符合线性的代码思维。我们有更简洁的方式处理 catch 块内的拒绝:
方案1:拆分逻辑到独立函数
把 catch 块里的异步逻辑抽成单独的 async 函数,在函数内部处理自己的 try/catch,主代码结构会保持清爽:
async function handleRejection() { console.log('caught rejection') try { await Promise.reject() } catch (e2) { console.log('caught rejection again') } } async function main() { try { await Promise.reject() } catch (e) { await handleRejection() } }
方案2:在 catch 块内结合 .catch() 链式调用
如果 catch 块里的逻辑不长,也可以直接对可能拒绝的 Promise 调用 .catch(),避免嵌套 try/catch:
async function main() { try { await Promise.reject() } catch (e) { console.log('caught rejection') await Promise.reject().catch(() => { console.log('caught rejection again') }) } }
内容的提问来源于stack exchange,提问作者Fyodor
相关产品推荐
相关产品推荐

