JS多层嵌套Try...Catch异常捕获:如何正确触发外层Catch逻辑
多Promise按顺序执行及异常捕获的方案
核心问题原因
finally块的固有执行逻辑是:无论所属try/catch代码块是正常执行结束,还是抛出异常终止,finally都会被触发,因此不能将「仅全部任务成功才需要执行的逻辑」放在finally块中。- 若
code1/code2是返回Promise的异步函数,普通同步try/catch无法捕获异步抛出的异常,必须搭配async/await使用才能实现异常捕获。
修正方案
场景1:code1/code2为同步函数
仅需要将成功提示从finally块移动到外层try块的最后一行即可,只有所有前置逻辑没有抛出异常才会执行成功提示:
try { try { code1() } catch(err) { console.log("Inner 1 ", err) throw err } try { code2() } catch(err) { console.log("Inner 2 ", err) throw err } // 仅全部执行成功才会走到此处 console.log("Full Success") } catch(err) { console.log("Outer", err) } // 若存在无论成功失败都要执行的清理逻辑,再保留finally块,否则可直接删除
场景2:code1/code2为返回Promise的异步函数(你需求的适用场景)
需要搭配async/await实现异步错误捕获,同时保证Promise严格按顺序执行,任意环节出错直接终止所有后续任务:
基础写法(适配少量固定任务)
async function runTasksInOrder() { try { try { // 加await等待异步执行完成,错误才能被try/catch捕获 await code1() } catch(err) { console.log("Inner 1 ", err) throw err } try { await code2() } catch(err) { console.log("Inner 2 ", err) throw err } console.log("Full Success") } catch(err) { console.log("Outer", err) // 抛出异常实现整个函数终止报错 throw err } } // 调用执行 runTasksInOrder()
简化写法(适配大量动态任务)
如果后续需要执行的Promise数量较多,可以用数组遍历的方式避免重复写嵌套try/catch:
/** * 按顺序执行多个返回Promise的任务 * @param {Array<Function>} promiseFns 按执行顺序排列的任务函数,每个函数调用后返回Promise */ async function runTasksInOrder(promiseFns) { try { for (let i = 0; i < promiseFns.length; i++) { // 前一个任务执行完成才会执行下一个 await promiseFns[i]() console.log(`第${i+1}个任务执行完成`) } console.log("Full Success") } catch (err) { console.log(`第${i+1}个任务执行失败`, err) console.log("Outer", err) throw err } } // 调用示例,传入按顺序执行的任务函数即可 runTasksInOrder([code1, code2])
内容的提问来源于stack exchange,提问作者Felix Jen
相关产品推荐
相关产品推荐

