我写了一些代码,发现了一些有趣的东西。
实施例1:
async function load(closure) {
try {
await closure();
} catch (error) {
console.log("error");
} finally {
console.log("finished");
}
}
load(async () => {
throw new Error();
});
console.log("hello");
该输出:
hello
error
finished
但是,如果我打电话:
实施例2:
load(() => {
throw new Error();
});
输出为:
error
finished
hello
你能解释一下这是怎么回事吗?
我知道调用await
会将执行排队到下一个时间点,因此第一个输出是预期的。
但是在第二个例子中,如果调用者使用的是await
,为什么closure
表现为一个同步函数?
这只会在抛出Error
时发生。如果我打电话...
实施例3:
load(() => {
return 1;
});
...那么closure
在下一个tick中被调用。
2条答案
按热度按时间nmpmafwu1#
查看文档
表达式的解析方式与Promise.resolve()相同:它总是被转换为本地Promise然后等待
在你的
Example 2
中,await
没有被使用,因为错误发生在promise创建之前(即在执行closure
函数期间)。该函数不返回任何值,因此不会转换为原生Promise。closure()
不是async
并抛出异常,则promise没有机会被创建,这就是为什么您首先看到error
和finished
日志。实际上,由于closure
函数尚未完全执行,因此未使用await
。closure()
不是async
并且返回一个值,它将被转换为promise,async函数将暂停直到下一个tick,这就是为什么你首先看到hello
。closure()
不是async
,并且返回了一个类似Promise.rejected()
的rejected promise,你会首先看到hello
,因为await
收到了一个rejected promise,async函数会像之前一样暂停,直到下一个tick。zysjyyx42#
两个示例之间的差异是由于
async/await
语法在函数执行中引入了隐式延迟,导致finally
块在console.log("hello")
语句之后执行。