2-23 说一下事件循环机制(node 浏览器)
node.js 事件循环机制
https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/
node.js 是可以运行在服务端 js 程序,因为执行 js 代码的v8 引擎被植入到了node中。
node.js 的事件循环机制,分为 timers
pending callbacks
idle, prepare
poll
check
close callbacks
六大阶段
阶段概述
- 定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。
- 待定回调:执行延迟到下一个循环迭代的 I/O 回调。
- idle, prepare:仅系统内部使用。
- 轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。
- 检测:setImmediate() 回调函数在这里执行。
- 关闭的回调函数:一些关闭的回调函数,如:socket.on('close', ...)
事件循环是不断的在等待着新的事件被添加进入专属队列中,直到条件被满足后才会被调用
web 浏览器事件循环机制
事件环的运行机制是,先会执行栈中的内容,栈中的内容执行后执行微任务,微任务清空后再执行宏任务,先取出一个宏任务,再去执行微任务,然后在取宏任务清微任务这样不停的循环。
eventLoop 是由JS的宿主环境(浏览器)来实现的;
事件循环可以简单的描述为以下四个步骤:
- 函数入栈,当Stack中执行到异步任务的时候,就将他丢给WebAPIs,接着执行同步任务,直到Stack为空;
- 此期间WebAPIs完成这个事件,把回调函数放入队列中等待执行(微任务放到微任务队列,宏任务放到宏任务队列)
- 执行栈为空时,Event Loop把微任务队列执行清空;
- 微任务队列清空后,进入宏任务队列,取队列的第一项任务放入Stack(栈)中执行,执行完成后,查看微任务队列是否有任务,有的话,清空微任务队列。重复4,继续从宏任务中取任务执行,执行完成之后,继续清空微任务,如此反复循环,直至清空所有的任务。
浏览器中的任务源(task):
宏任务(macrotask)
:
宿主环境提供的,比如浏览器
ajax、setTimeout、setInterval、setTmmediate(只兼容ie)、script、requestAnimationFrame、messageChannel、UI渲染、一些浏览器api微任务(microtask)
:
语言本身提供的,比如promise.then
then、queueMicrotask(基于then)、mutationObserver(浏览器提供)、messageChannel 、mutationObersve