Nodejs学习心得沉淀(四)——事件循环
在这篇文章中,你会了解到
- 宏队列微队列与宏任务微任务
- event loop执行模型要点
注意,因为其它关于Event Loop的文章已经写的很好了,并且配有大量的实例(文末链接),因此本文中不会大量讲解事件循环的机制,只会将事件循环中的一些要点提出,让大家能够对事件循环有一个宏观层面的清晰认识。
注意:node在11版本之后的eventloop执行与浏览器一致了,在这之前浏览器和nodejs分别各有一套Event Loop
JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。这个模型与其它语言中的模型截然不同,比如 C 和 Java,libuv这个库提供两个最重要的东西是事件循环和线程池,两者共同构建了异步非阻塞I/O模型。
一、libuv
- libuv是一个高性能的,事件驱动的I/O库,并且提供了跨平台(如windows, linux)的API。
- 它的核心工作是提供一个event-loop,还有基于I/O和其它事件通知的回调函数。
- libuv会负责将来自操作系统的事件收集起来,或者监视其他来源的事件。
伪代码表示如下
while there are still events to process:
e = get the next event
if there is a callback associated with e:
call the callback
这是lilbuv内部的一个结构,事实上,为了理解Event Loop,我们并不需要对用C语言写的libuv有多么深入的了解,只需要知道其内部关于Event Loop的执行原理即可
二、宏队列微队列与宏任务微任务
该图展示的是libuv提供的事件循环中的六个阶段,从概念上,这六个阶段都可以分别看作是一个宏队列
- timers阶段:这个阶段执行setTimeout和setInterval预定的callback
- I/O callback阶段:执行除了close事件的callbacks、被timers设定的callbacks、s
- etImmediate()设定的callbacks这些之外的callbacks
- idle, prepare阶段:仅node内部使用
- poll阶段:获取新的I/O事件,适当的条件下node将阻塞在这里
- check阶段:执行setImmediate()设定的callbacks
- close callbacks阶段:执行socket.on(‘close’, …)这些callbacks
而微任务队列就是穿插在宏队列之间执行的
宏任务包括: setTimeout、setInterval、 setImmediate、requestAnimation、IO、UI rendering
微任务包括: process.nextTick(Node)、Promise、Object.observe、MutationObserver
-
JavaScript代码执行的具体流程(可以看带你彻底弄懂事件循环)
-
有哪些是常见的宏任务,又有哪些是微任务
-
什么是回调栈、回调队列,以及堆,里面存放的是什么?
-
微任务是在宏任务之前先执行的
-
如果在执行microtask的过程中,又产生了microtask,那么会加入到队列的末尾,也会在这个周期被调用执行(就是说依旧会在宏任务之前执行)
-
特立独行的process.nextTick(),执行的优先级高于微任务,底于script脚本
-
事件循环的几个特点(执行至完成、添加消息、零延迟、多个运行时互相通信)
看[并发模型与事件循环](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop)这篇文章
-
通过大量的实践去理解事件循环的原型原理(几乎每篇文章都会有)
参考杨浩老师的课程,我们用一个简单的栗子来看一下事件循环的内部调用机制
const eventLoop = {
queue:[],
init(){
while(this.queue.length){
var callback = this.queue.shift()
callback()
}
setTimeout(this.init.bind(this),50)
},
add(callback){
this.queue.push(callback)
}
}
eventLoop.init();
setTimeout(()=>{
eventLoop.add(
function () {console.log(1)}
)
},400)
setTimeout(()=>{
eventLoop.add(
function () {console.log(2)}
)
},800)
感谢阅读,欢迎批评指正,希望大家能够在追求卓越中不断进步,让优秀成为一种习惯~
参考文章: