我写了下面这些代码:
const delay = async (time) => {
return new Promise(resolve => setTimeout(resolve, time))
}
const busy = (time) => {
const now = new Date()
while(new Date() - now < time){}
}
const getNum = () => {
console.log("getnum 执行")
return new Promise(async (resolve,reject) => {
console.log("promise 开始")
resolve(1)
addMicro("haha")
console.log("promise 结束")
addMicro("===")
});
};
const addMicro = (str) => {
Promise.resolve().then(() => {
console.log(`micro task ${str}`);
});
}
try {
await getNum()
console.log("1212") // 先执行 1212 还是 micro task ,先执行 1212
} catch (err) {
console.error(err)
}
并且我本来以为 resolve(1) 会将 await 后的代码先添加到 microTaskQueue ,然后再是 addMicro 函数添加了两个 microTasks ,所以队列先进先出应该先打印 1212 再是两个 "micro task xxx" 但是结果却是先打印了 "micro task xx"再打印 1212
问了 chatGPT 完全的胡言乱语,还是问题 copilot 得到的答案似乎有些说服力:
Your question is about the execution order of microtasks in JavaScript.
The key to understanding this is to recognize that await is essentially syntactic sugar for Promise.then(). When you use await, the code after the await expression is wrapped in a Promise.then() callback.
In your example, await getNum() is equivalent to getNum().then(() => { console.log("1212") }).
Now, let's analyze the execution order:
getNum() is called, which returns a Promise.
The Promise is resolved immediately with the value 1.
The addMicro("haha") and addMicro("===") calls are executed, which add microtasks to the microtask queue.
The Promise.then() callback associated with await getNum() is added to the microtask queue.
The microtask queue is executed. Since addMicro("haha") and addMicro("===") were added to the queue earlier, they are executed first, logging "micro task haha" and "micro task ===".
Finally, the Promise.then() callback associated with await getNum() is executed, logging "1212".
So, to answer your question, the code after await is not added to the message queue earlier than the microtasks added by addMicro(). Instead, the microtasks are executed in the order they were added to the queue.
Here's a simplified example to illustrate this:
javascript
CopyInsert
Promise.resolve().then(() => console.log("A"));
console.log("B");
Promise.resolve().then(() => console.log("C"));
Output:
CopyInsert
B
A
C
In this example, "B" is logged first, followed by "A" and then "C". This is because the microtasks are executed in the order they were added to the queue.
I hope this explanation helps clarify things! Let me know if you have further questions.
11 Sources
ZC
You
5:14 pm, Feb 20, 2025
The Promise.then() callback associated with await getNum() is added to the microtask queue.
why this action is behind the 3 implied adding micro_task action? Isn't it triggered by resolve(1)?
Codeium
5:14 pm, Feb 20, 2025
You are correct that the resolve(1) call triggers the addition of the Promise.then() callback associated with await getNum() to the microtask queue.
However, there's a subtle detail to consider: when resolve(1) is called, it doesn't immediately add the Promise.then() callback to the microtask queue. Instead, it marks the Promise as resolved and schedules the execution of the Promise.then() callback.
In JavaScript, when a Promise is resolved or rejected, the associated Promise.then() callbacks are not executed immediately. Instead, they are added to the microtask queue at the end of the current execution context.
In your example, when resolve(1) is called, it marks the Promise as resolved, but the Promise.then() callback associated with await getNum() is not added to the microtask queue immediately. Instead, it's added to the queue at the end of the current execution context, which is after the addMicro("haha") and addMicro("===") calls have already added their microtasks to the queue.
This is why the microtasks added by addMicro("haha") and addMicro("===") are executed before the Promise.then() callback associated with await getNum().
To illustrate this, consider the following example:
javascript
CopyInsert
Promise.resolve().then(() => console.log("A"));
console.log("B");
resolve(); // assume this resolves a Promise
Promise.resolve().then(() => console.log("C"));
Output:
CopyInsert
B
C
A
In this example, the resolve() call marks the Promise as resolved, but the Promise.then() callback associated with A is not executed immediately. Instead, it's added to the microtask queue at the end of the current execution context, which is after the console.log("C") statement has already been executed.
I hope this explanation helps clarify things! Let me know if you have further questions.
但是它给的例子我也是看不懂,很怕它又是在信口开河所以来问一下,蹲个佬解答一下,是
懒得去翻太多资料了,其实翻资料的时候也像个无头苍蝇,所以借助一下社区的力量。。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.