浅谈JS宏任务与微任务

170 阅读2分钟

前言

相信大家在面试的时候,经常会遇到下面的试题,让回答先后输出的是什么。

console.log('script start');

setTimeout(function() {
   console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {    
    console.log('promise1');
}).then(function() {    
    console.log('promise2');
});

console.log('script end');

对于这样的试题大家都不陌生吧,其实知识点就是考察我们对于JS的运行机制、JS的宏任务、JS的微任务这些是否了解。话不多说,下面开始浅谈一下。

JS运行机制

javaScript语言的一大特性就是单线程,也就是说,同一时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务,这样导致的问题就是:如果js执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

1. js的同步任务与异步任务
  • 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
  • 异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
2. 任务队列

任务队列又分为宏任务微任务。整个script可以当成一个宏任务,先执行宏任务,执行完成,执行微任务,完成之后再执行宏任务,直到把所有的任务都执行完成。可以结合下图看一下大概执行顺序。

5782588-b998a276f9b1d775.webp

3. 宏任务

  • 主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
事件浏览器node
setTimeout
setInterval
setImmediatex
requestAnimationFramex

4. 微任务

  • 主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)
事件浏览器node
process.nextTickx
MutationObserverx
Promise.then catch finally

结束语

看完之后,不知道大家有没有了解宏任务与微任务,可以看一下文章最开始的demo,大家可以尝试执行一下输出顺序。