5

我想很多人都见过或听过这种题。

setTimeout(() => { console.log('settimeout') });

new Promise((resolve) => {
    resolve('');
    console.log('promise-resolve');
}).then(() => {
    console.log('promise-then');
});

console.log('script');

当你把上述的代码块放到浏览器中执行的时候会发现输出顺序是:

promise-resolve
script
promise-then
settimeout

为什么会是这样的输出顺序呢?这就要提到事件循环、宏任务和微任务的概念了。众所周知,JavaScript是一个单线程的语言,单线程意味着代码会自上而下依次执行,如果有一个耗时的操作,那么页面就会卡死,基于此,便有了异步的概念,而宏任务微任务都是属于异步任务。而JavaScript一次性不能处理多个任务,所以便需要一个能有效执行各个任务的逻辑,这便是事件循环

每次循环都会先执行宏任务,然后查找是否有可执行的微任务,有的话就执行微任务,否则执行下一个宏任务,以此循环。

宏任务:Script代码块,setTimeout,setInterval,I/O操作,setImmediate。
微任务:Promise,process.nextTick,MutationObserver


WillemWei
491 声望37 粉丝