【发布时间】:2021-11-10 17:13:51
【问题描述】:
概要:
在 Node.js 事件队列中,以及像“new Promise((r) => setTimeout(r, t));”这样的代码中,setTimeout() 是现在评估的,在微队列中为 Promise 解析,还是在哪里?
详情:
我正在阅读 Distributed Systems with Node.js(Thomas Hunter II,O'Reilly,第一版的第 3 版)。它告诉我 Node.js 依次通过每个队列:
- 轮询:适用于大多数事情,包括 I/O 回调
- 检查:setImmediate 回调
- 关闭:关闭连接时
- 计时器:当 setTimeout 和 setInterval 解析时
- 待处理:特殊系统事件
在每个队列为空后还会评估两个微队列,一个用于 promises,一个用于 nextTick()。
在本书的第 13 页,他有一个示例,其中 await 调用了一个返回“new Promise((r) => setTimeout(r, t));”的函数。本书代码为:
const sleep_st = (t) => new Promise((r) => setTimeout(r, t));
const sleep_im = () => new Promise((r) => setImmediate(r));
(async () => {
setImmediate(() => console.log(1));
console.log(2);
await sleep_st(0);
setImmediate(() => console.log(3));
console.log(4);
也就是说,
setImmediate(() => console.log(1));
console.log(2);
Promise.resolve().then(() => setTimeout(() => {
setImmediate(() => console.log(3));
console.log(4);
我认为是这样的:
-
程序从 Poll 队列中的一个任务开始,第 13 页代码。它开始运行。
-
检查队列得到一个任务,“2”打印到控制台。
-
“await sleep_st(0)”将调用 setTimeout,它会放置一个 Timer 队列中的任务。由于超时时间为零,所以当我们 访问定时器队列会有工作要做。 sleep_st(0) 返回一个 Promise。
-
这结束了轮询队列的工作。
-
现在结果微队列开始了。我的代码继续执行。这应该从 setImmediate() 和 console.log(4)。
这意味着控制台的输出是“2 4”。但是,这本书说正确的顺序是“2 1 4 3”。也就是说,Check 的事件队列,也许还有 Timer,都参与其中。
那么,Promise 结果微队列中会发生什么?
【问题讨论】:
-
不确定您是如何到达
Promise.resolve().then(() => setTimeout(() => {的。你是说那行中的sleep_st(0).then(() => {吗? -
“你如何到达”的代码抄录自本书第13页。作者以两种方式提出了逻辑。
标签: javascript node.js async-await promise