Event Loop
Jan 22, 2019
1.进程与线程
面试题:进程与线程区别?JS 单线程带来的好处?
- 进程:描述了 CPU 在运行指令及加载和保存上下文所需的时间
- 线程:是进程中的更小单位,描述了执行一段执行所需的时间
当在浏览器打开一个 Tab 页时,就是创建了一个进程,一个进程中可以有多个线程,比如渲染线程、JS 引擎线程、HTTP 请求线程等等。
JS 单线程可以达到节省内存,节约上下文切换时间、没有锁的问题的好处。在 JS 运行时可能会阻止 UI 渲染,说明两个线程是互斥的,避免 JS 修改 DOM 的时候 UI 线程在工作就可能导致不能安全渲染 UI。
2.执行栈
面试题:什么是执行栈?
可以理解为是一个存储函数调用的栈结构,遵循先进后出的原则。
当开始执行 JS 代码时,首先会执行一个 main 函数,然后执行我们的代码。根据先进后出的原则,后执行的函数会先弹出栈。
当我们使用递归的时候,因为栈可存放的函数是有限制的,一旦存放了过多的函数且没有得到释放的话,就会出现栈溢出的问题
3.浏览器中的 Event Loop
面试题:异步代码执行顺序?解释一下什么是 Event Loop ?
执行 JS 代码的时候其实就是往执行栈中放入函数,遇到异步代码时,会被挂起并在需要的时候加入到 Task 队列中。执行栈为空,Event Loop 就会从 Task 队列拿出需要执行的代码并放入执行栈中执行。
- 宏任务包括 :script , setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering。
- 微任务包括 :process.nextTick ,promise ,MutationObserver。
例子:
1 | console.log('script start') // 1 |
所以 Event Loop 执行顺序如下所示:
- 首先执行同步代码,这属于宏任务
- 当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
- 执行所有微任务
- 当执行完所有微任务后,如有必要会渲染页面
- 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数