前端JavaScript 执行机制(微任务,宏任务,同步任务,异步任务)
最近面试的时候,面试官问了一个过于微任务,宏任务的面试题,当时回答的挺含糊,原因也是自己对微任务,宏任务本身就不是很理解。之后看了不少文档,自己做了一些总结:要将微任务,宏任务就不得不说JavaScript的执行机制了
JavaScript的执行机制
1.关于javascript
首先我们要是知道javascript是一门 单线程 语言。什么是单线程呢?这就好比只有一个窗口的办事处,人们在排队办事,只有当前面的人办好后,后一个人才能办自己要办的事。可是聪明的我们会发现这么一个问题,在我们浏览某些含有超清图片的新闻页面时,按照javascript的单线程的执行机制,网页会花很多时间去加载图片,当图片加载不出来时,下面的内容就不会加载出来。很明显这样是非常不好的体验,因此就产生了两种任务:
- 同步任务
- 异步任务
2.javascript事件循环
当我们打开网站时,网页的渲染过程就是一大堆同步任务,比如页面骨架和页面元素的渲染。
而像加载图片音乐之类占用资源大耗时久的任务,就是异步任务。
关于这部分有严格的文字定义,但本文的目的是用最小的学习成本彻底弄懂执行机制,所以我们用导图来说明:
按图来说就是:
- 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
- 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
- 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
- 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
3. 同步任务,异步任务,宏任务,微任务之间的关系
同步任务是按照执行顺序执行的,
异步任务包括:setTimeOut、setInterval、promise、process.nextTick,
其中一般的js代码、setTimeOut、setInterval属于宏任务,
promise.then、process.nextTick属于微任务。
4.javascript事件循环,宏任务,和微任务的关系
如图所示:
总结:
- 一般的JavaScript代码(同步)的属于宏任务,定时器相关的异步代码,包括setTimeOut、setInterval等也属于宏任务,promise、 process.nextTick属于微任务;
- 同步的代码会按照执行顺序顺序执行,遇到异步代码的时候,属于宏任务的放到宏队列,微任务放到微队列,其中promise需要resolve或者reject才会执行then或者catch里面的内容,其他的放到队列的属于回调函数的内容。
- 执行顺序是宏任务-微任务-宏任