为何在lastFunction参数中await Promise时错误未被try/catch捕获?
为什么在函数参数中直接await Promise时错误无法被catch捕获?
你遇到的这个现象,核心是Promise未处理拒绝的警告和实际错误捕获时机的差异,我们一步步拆解清楚:
先看你的Promise定义
你的promise2函数里,在Promise构造函数的同步执行器中抛出了错误:
const promise2 = () => { return new Promise((res, rej) => { throw new Error('second one broke') }) }
这种错误会被Promise自动捕获,把promise2()返回的Promise置为拒绝状态,不会直接同步抛出到全局。但这里有个关键细节:当这个拒绝状态的Promise被创建后,如果在一段时间内没有被await或者.catch()处理,浏览器会触发未处理Promise拒绝的警告——你在控制台看到的“错误没被捕获”,大概率是这个警告混淆了你。
两种写法的执行差异
写法1:在lastFunction参数中直接await
try { const res1 = promise1() // 得到pending状态的Promise,需要1秒才会resolve const res2 = promise2() // 得到rejected状态的Promise,立即处于拒绝状态 const finalResponse = await lastFunction(await res1, await res2) } catch (err) { console.log('Catching error') console.log(err) }
执行流程是这样的:
- 先创建
res1(pending)和res2(rejected)两个Promise对象 - 执行
await lastFunction(...)时,JavaScript会先计算所有函数参数,再调用lastFunction:- 首先等待
await res1完成:这需要整整1秒时间 - 在这1秒的空窗期里,
res2这个已拒绝的Promise没有被任何代码处理,浏览器就会抛出未处理Promise拒绝的警告 - 1秒后
res1resolve,开始计算第二个参数await res2:此时await会把Promise的拒绝转化为错误抛出,这个错误会被try/catch正常捕获,控制台会输出Catching error和错误信息
- 首先等待
你可能把提前出现的警告当成了“错误没被捕获”,但实际上错误最终还是被处理了,只是中间有个警告的时间差。
写法2:单独await每个Promise
try { const res1 = await promise1() // 等待1秒后得到结果 const res2 = await promise2() // 立即处理rejected的Promise,抛出错误并被捕获 const finalResponse = await lastFunction(res1, res2) } catch (err) { console.log('Catching error') console.log(err) }
这种写法的执行逻辑更连贯:
- 先
await res1:等1秒后拿到结果 - 接着执行
await promise2():promise2()返回的拒绝Promise被立即await处理,没有空窗期触发未处理拒绝的警告,错误直接被catch块捕获
如何避免写法1中的警告?
如果你想保留参数里await的写法,同时消除警告,可以用Promise.all同时等待两个Promise,这样两个Promise的状态会被同步处理,不会出现空窗期:
try { const [res1Val, res2Val] = await Promise.all([promise1(), promise2()]) const finalResponse = await lastFunction(res1Val, res2Val) } catch (err) { console.log('Catching error') console.log(err) }
这种写法里,Promise.all会同时监听两个Promise的状态,任何一个拒绝都会立即触发错误,既不会有未处理拒绝的警告,错误也能被catch正常捕获。
内容的提问来源于stack exchange,提问作者Olly
相关产品推荐
相关产品推荐

