一、一些前置知识
1. JavaScript是单线程
总所周知, JS是单线程的脚本语言 ,也就是说,每次都只能执行一项任务,其他任务都需要排队等待 。为了协调事件、用户交互、脚本、UI渲染和网络处理等行为,防止主线程阻塞,Event Loop方案应运而生。
2. 进程
进程是系统分配的独立资源,是程序执行时的一个实例,是系统进行资源分配和调度的基本单位,进程是由一个或者多个线程组成的。
3. 线程
线程是进程的执行流,是CPU调度和分派的基本单位,同个进程之中的多个线程之间是共享该进程的资源的。
4. 宏任务(macrotask)在新标准叫 task
宏任务主要包括:script(整体代码)、setTimeout、setInterval、setImmediate、I/O、ui rendering
5. 微任务(microtask)在新标准中叫 jobs
微任务主要包括:Promise、process.nextTick、MutationObserver(HTML5新特性)
6. 同步任务
在主线程上,排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
7. 异步任务
不进入主线程,而进入“任务队列”的任务,只有“任务队列” 通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行
二、Event Loop(事件循环)
Event Loop(事件循环中),每次一循环称为一次tick,下面列举了每一次tick的任务
- 执行栈会选择最先进入的队列的宏任务
- 执行其中的所有同步任务
- 检查是否有微任务 , 如果有,则全部执行
- 浏览器更新渲染
总结:
- 所有的任务都存在两个队列: 执行队列和任务队列
- 执行队列中的代码都是同步的 ,任务队列中的代码都是异步的
- 任务进入到执行队列 , 首先执行其中的同步代码 ,并将异步代码放到任务队列排队等候, 微任务也会放到微任务队列,当所有的同步代码完成后, 会执行所有的微任务,最后是异步代码