宏任务和微任务的区分

JavaScript011

宏任务和微任务的区分,第1张

说到JavaScript的事件循环(Even loop)就会提到同步事件和异步事件

整个JS在运行过程中主要执行以下事件循环

上面就是一个简单的事件循环过程,那么在异步任务中还有宏任务和微任务的区别,他们具体的定义如下

微任务是异步任务中最早开始执行的,它可以是同步任务、宏任务执行时产生的,微任务能够在 实时性和效率 之间做一个有效的权衡,一般可以总结为一下几个方法

这里 Promise 、 Async/Await 、 Object.observe 以及 MutationObserver ,都是 JS语法内置的方法 , 不需要浏览器支持,可以理解为直接用JS引擎就能处理掉的任务

可以理解为每一个宏任务进程中都包含了一个微任务进程, 事件的触发 非JS部分 以及 定时器 都可以归为宏任务

宏任务会触发新一轮的事件循环,下图就是宏微任务的执行流程图,

https://juejin.cn/post/6932263539839074311?utm_source=gold_browser_extension#heading-2

https://www.jianshu.com/p/75107522813f

https://www.jianshu.com/p/bfc3e319a96b

https://juejin.cn/post/6880787856353132552

https://www.cnblogs.com/fangdongdemao/p/10262209.html

最近几天,面试了几个应聘的。有一道面试题,答案真是千奇百怪。就是这么一道题:

setTimeout(() =>{

console.log("setTimeout")

})

let p1 =new Promise((resolve) =>{

console.log("Promise1")

    resolve("Promise2")

})

p1.then((res) =>{

console.log(res)

})

console.log("over")

当然有的答对的可能是见过这么一道相似的类似题目,我们来简单聊一聊这是一道什么样的题。

接触JS的肯定都知道,JS是单线程的。而单线程就意味着所有的任务都要进行排队,依次执行,这就是任务队列。但是会有那样的任务执行起来很耗时间,而我们还有很多没有利用的CPU空间。所以就产生了:JS中任务是有同步(synchronous)和异步(asynchronous)的分别的。同步就是顺次执行的那一种,而异步就是需要等待的那一种。同步和异步的执行路线是不同的:同步会进入主线程顺次执行。只有前一个执行结束才会执行下一个;而异步会进入一个等待的队列,可以理解为等待中的任务队列(任务队列就是一个先进先出的队列结构,主线程的执行队列的读取是自动的)。在这里异步任务会在Event Table中注册相应的回调函数。当指定的步骤完成了,Event Table会将注册了的回调函数推送到Event Queue,在Event Queue这里进行等待上场。当主线程内的任务执行完毕为空之后,就会到Event Queue读取相应的函数,进入主线程执行。这个过程不断重复构成Event Loop。

这个就是同步与异步的简单过程。

但是,会有一个疑问,向上面的那道题目中的SetTimeout和promise都是异步任务那他俩的执行属性呢?难道是顺次,这个还真不一定。

JS的异步也是有一个机制的,就是会分为宏任务和微任务。宏任务和微任务会放到不同的event queue中,先将所有的宏任务放到一个event queue,再将微任务放到一个event queue中。执行完宏任务之后,就会先从微任务中取这个回调函数执行。

那么什么是宏任务呢,一般就是setTimeout、setInterval、script、I/O

微任务就是,Promise\process.nextTick

让我们回到那道题,首先会执行script下的宏任务,解析,遇到setTimeout,判断它是一个宏任务类型,将其放到一个宏任务的queue中;遇到Promise,开始执行,打印 Promise1 ;往下遇到then,判断是个微任务,放到微任务的队列中,等待执行;继续解析,打印 over 。查证本轮次的宏任务都执行完毕了,开始执行本轮的微任务,发现有一个then的回调函数,打印 Promise2 , 到这里微任务页执行完毕了,这样本轮次的Loop全部执行完毕,开始下一轮次的Loop。发现宏任务的队列有一个setTimeout的回调函数,打印 setTimeout 。

1.宏观任务(macro task): 由宿主(node、浏览器) 发起的任务,如setTimeOut、setInterval、setImmediate、I/O

2.微观任务(micro task):由 js引擎 发起的任务,如process.nextTick、promise、mutationObserver