事件循环,宏任务,微任务

问题

js
1234567891011121314
console.log('1');

setTimeout(() => {
  console.log('2');
}, 0);

new Promise((resolve) => {
  console.log('3');
  resolve();
}).then(() => {
  console.log('4');
});

console.log('5');

打印顺序是1,3,5,4,2。在这段代码中1,3,5都是同步任务,所以从上到下立即执行。setTimeout中的是宏任务,.then中的是微任务。优先级是:微任务>宏任务。常见的微任务有Promise.then / .catch / .finally,process.nextTick(node环境),常见的宏任务有script(整体代码,这是第一个宏任务),setTimeout / setInterval (定时器),DOM 事件回调 (如点击事件),ajax 请求回调。

所以事件循环的顺序是:同步代码先执行(这属于当前的宏任务)->同步代码执行完,立刻清空微任务队列(所有加塞的 Promise.then)->渲染页面(如果有需要)->取出下一个宏任务(比如 setTimeout)->重复第二步

小测验:

js
1234567891011121314151617181920212223242526
console.log('1'); // 同步

setTimeout(function() {
    console.log('2'); // 宏任务
}, 0);

async function async1() {
    console.log('3'); // 同步?还是异步?
    await async2();
    console.log('4'); // 这里的代码相当于在 .then 里
}

async function async2() {
    console.log('5');
}

async1();

new Promise(function(resolve) {
    console.log('6');
    resolve();
}).then(function() {
    console.log('7');
});

console.log('8');

答案是:1, 3, 5, 6, 8, 4, 7, 2, 注意await async2();是同步代码