前言
js引擎真算是galagame男主吧!同步代码和异步代码就像是男主的后宫们,等待着js引擎不断的循环遍历。
js引擎单线程的执行机制
- 什么是单线程
- 好比做人要专一,好比一个人干活,大部分人一次只能全心全意做一件事,这就是单线程最好的理解方式。
- 专一的js引擎
- js引擎在代码的执行过程中是专一的,一次性只能处理一份代码。没有办法同一时刻处理两份代码。
异步的诞生
同步&异步
js引擎执行代码时,只开一个工作线程工作,为提高执行效率执行效率,碰到需要耗时的代码时,v8引擎无需等待,可以将耗时代码放到任务队列中,等不耗时的代码执行完毕后,回头再执行。
- 而其中:
- 不耗时的代码,我们称之为同步代码
- 耗时的代码,我们称之为异步代码
event-loop (事件循环机制)
1. 简单意义上的事件循环过程(仅供初步理解)
简单意义上来讲js代码的执行是不断重复(执行同步代码 =》 执行异步代码)这一过程.
- 我们都明白,js引擎会先执行同步代码,将耗时的异步代码放入任务队列中,等同步代码执行完毕,再回头执行耗时代码。这就构成了一个事件流,而js代码的执行就好比于不断的重复该过程
2. 任务等待队列
- 异步代码,是我们主观认为下会耗时执行的代码,js引擎会在执行过程中将异步代码单独提走,放到异步任务队列的中等待执行,但是异步代码之间亦有差距。
3. 宏任务&微任务
按照异步代码的执行时机划分,异步会被放入两种任务队列等待执行,那就是宏任务队列与微任务队列,被放入相应队列的异步代码,我们称之为宏任务与微任务。
- 宏任务:等待下一轮循环执行的代码。
- 比如:setTimeout(),setInterval(),ajax,I/O,UI-rendering页面渲染等
- 特点:
- 依赖外部资源 ,比如:setTimeout()依赖外部资源定时器,ajax依赖网络
- 执行时机:需要等待下一次事件循环才能够被执行。
- 微任务:
- 比如:promise.then(),process.nextTick(),MutationObserver
- 特点:
- 不依赖外部资源,比如 promise.then()依赖promise对象状态,这都是js环境自身拥有的资源。
- 执行时间,本次事件循环同步代码执行完毕后,立马执行
4. 事实意义上的事件循环机制(event - loop)
js代码的执行是不断的重复(从宏任务队列中取出一个宏任务=》执行宏任务内部同步代码=》清空微任务队列)这一过程,我们称之为事件流。
- 从宏任务队列中取出宏任务:
- 一份js代码全局就是一个宏任务
- 如果宏任务队列为空,则js引擎就陷入等待,直到新的宏任务出现
- 执行宏任务内部同步代码:
- 执行宏任务内部过程中,所有的同步代码直接执行。
- 异步代码,则被放入相应的(宏任务/ 微任务)等待序列
- 清空微任务队列:
- 同步代码执行完毕后,立马开始执行微任务队列中等待执行的所有异步代码=》执行所有的微任务
- 如果微任务队列为空,则直接进入下一步。
- 重复第一步