#js

示例

console.log(1);
// The first line executes immediately, it outputs `1`.
// Macrotask and microtask queues are empty, as of now.
 
setTimeout(() => console.log(2));
// `setTimeout` appends the callback to the macrotask queue
// - macrotask queue content:
//   `console.log(2)`
 
Promise.resolve().then(() => console.log(3));
// The callback is appended to the microtask queue
// - microtask queue content:
//   `console.log(3)`
 
Promise.resolve().then(() => setTimeout(() => console.log(4)));
// The callback with `setTimeout(...4..)` is appended to microtasks
// - microtask queue content:
//   `console.log(3); setTimeout(...4..)`
 
Promise.resolve().then(() => console.log(5));
// The callback is appended to the microtask queue
// - microtask queue content:
//   `console.log(3); setTimeout(...4..); console.log(5)`
 
setTimeout(() => console.log(6));
// `setTimeout` appends the callback to macrotasks
// - macrotask queue content:
//   `console.log(2); console.log(6)`
 
console.log(7);
// Outputs 7 immediately.

同步代码执行完后,会先清空微任务队列,再进入事件循环

输出:1 7 3 5 2 6 4

示例

console.log(1);
// 同步代码先执行,输出"1"。
await new Promise(res => setTimeout(res, 0));
// new Promise(...)构造函数里的代码会立即执行,将setTimeout(res,0)被放入宏任务队列
// 然后await让出主线程,进入事件循环,取下一个宏任务执行,也就是执行res()
// Promise已resolve,await返回
console.log(2);
// await后的代码(也就是`Promose.then`)会被放入微任务队列
// 然后清空执行微任务队列

也就是说,要强行把res()放到下一宏任务执行,用: await new Promise(res => setTimeout(res, 0))

参考