这个计算过程中的宏任务队列和微任务队列状态

3

这个问题与Difference between microtask and macrotask within an event loop context非常相似,但更为具体,因为它要求解释一个明确的例子:我认为出于这个原因,它不应被视为重复。

在node.js执行此代码期间,Macrotask队列和Microtask队列处于什么状态?

console.log("A1");

(async ()=> {

    console.log("1")

    f = async ()=>{console.log('2')}

    await f()

    console.log("3")

})()

console.log("A2");

输出:

A1
1
2
A2
3

我期望的输出结果是:A1, A2, '1', '2', '3'

根据这样的推理:log A1 --> 将匿名函数放入微任务队列 --> log A2 --> 执行匿名函数 log 1,将 f 放入微任务队列 --> 从微任务队列执行 f --> log 2 --> log 3

我错在哪里了?(另外,顶级异步函数是如何排队的?)

备注:实际使用的命令是 npx babel-node myscript.js


1
没有特定原因,我只是在使用Babel处理其他内容时顺手用了它。 - tjb
(仅返回翻译文本):对于潜水者:Babel 输出也是最新的 Node.js 本地化此代码的方式。 - T.J. Crowder
1个回答

1
您看到这种行为是因为async函数在第一个await、显式return或隐式return(代码执行到函数末尾)之前同步运行。
我将稍微更改代码,给外部的async函数命名,以便更容易讨论。
console.log("A1");
const outer = async () => {
    console.log("1")
    f = async ()=>{console.log('2')}
    await f()
    console.log("3")
};
outer();
console.log("A2");

这是发生的情况:
  1. console.log("A1") 运行(当然)。
  2. 调用 outer()
  3. outer 的同步部分运行,因此它:
    • 运行 console.log("1")
    • 创建 f
    • 调用 f()
  4. f 的同步部分运行,因此它:
    • 执行 console.log('2')
  5. 此时,f 隐式返回,因此它将其 promise 返回给 outer。该 promise 已经被履行,其值为 undefined。(请参见规范中的 这里。)
  6. outer 等待 f 的 promise,因此它将其 promise 返回给调用者(但这不重要)。
  7. outer 等待 f 的 promise 会排队一个微任务来继续执行 outer,因为 f 的 promise 已经被解决。
  8. console.log("A2") 运行。
  9. 微任务运行,允许 outer 继续执行并运行 console.log("3")

“implicit await” 或 “implicit return” 是什么意思?隐式等待是否意味着等待一个 Promise 解决? - tjb
@tjb - 抱歉,"(implicit or explicit)" 只是指 return,我会看看能否重新表述。显式的返回当然是 return;return value;。隐式返回只是代码执行到函数结尾,就像 fouter 一样。 - T.J. Crowder
@tjb - 我已经更新了代码以处理隐式或显式的事情,并添加了更多细节。 - T.J. Crowder
1
谢谢,我觉得我开始理解了,但是我已经这么想过很多次了 :) - tjb
@tjb - 哈哈,我也经历过! - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接