非异步函数被await且抛出异常时,调用方代码是否也会抛出异常?
问题解答
你给出的代码实际运行表现和你预期一致:会直接同步抛出Error,异常不会被包装为Promise的resolve值,也不会赋值给foo变量。
你产生困惑的核心原因是忽略了ECMAScript规范中?前缀记号的语义:该记号是ReturnIfAbrupt的简写,含义为如果前序操作返回突然完成(abrupt completion),则立刻中断当前流程,将该突然完成结果向上抛出,不再执行后续步骤。
我们对照你列出的await表达式执行规则逐行分析:
AwaitExpression : await UnaryExpression 1. Let exprRef be the result of evaluating UnaryExpression. 2. Let value be ? GetValue(exprRef). 3. Return ? Await(value).
- 执行第1步时,调用
boo()会直接抛出错误,得到类型为throw的突然完成结果存入exprRef - 执行第2步时,
? GetValue(exprRef)会先判断exprRef的类型:因为是突然完成,直接中断流程向外抛出该错误,不会执行后续的GetValue和第3步的Await调用
你可以通过如下测试代码验证行为:
async function test() { function boo() { throw new Error('同步抛出错误'); } try { let foo = await boo(); console.log('不会执行到这里'); } catch (err) { console.log(err.message); // 输出:同步抛出错误 } } test();
内容的提问来源于stack exchange,提问作者Ilya Loskutov
相关产品推荐
相关产品推荐

