嗨各位大大~
我是Robin
这週来分享一下我这週学习的Node's EventLoop
本篇学习目标◑ω◐:
初步试探Node同步异步执行顺序认识 Node’s EventLoop验收初步试探Node同步异步执行顺序
先试试看在读这篇的你对于node中同步异步的掌握。
试着把以下的顺序写下来
// foo.jssetTimeout(() => console.log(1));setImmediate(() => console.log(2));Promise.resolve().then(() => console.log(3));process.nextTick(() => console.log(4));(() => console.log(5))();
想好答案了吗?
答案会是
5431 //有可能是22 //有可能是1
如果你答对了(猜对不算)!(๑• . •๑)
恭喜你可以把文章关掉了(反正点阅已经被我骗到了)
完全正确也可以接着看我的文章验证自己和我的叙述的是否相同啦~
没有答对的不要气馁让我们一起学习吧~(●´ω`●)ゞ
Node’s EventLoop 初步认识
接续上篇的JS使用的EventLoop,
在Node中又有什么不同?
我会以我的观察来分享一下。
他们听起来是一样的,( ͡° ͜ʖ ͡°)
但是实际实作方式真的是相差甚远Σ(゚Д゚;≡;゚д゚)
Node跟浏览器的EventLoop比複杂许多。
Node的EventLoop是基于libuv函式库实作出的
libuv是使用C++写出来的,听说这个函示库一开始就是为了node而写的。
我们来看看官方文件说了啥(,,・ω・,,)
When Node.js starts, it initializes the event loop, processes the provided input script (or drops into the REPL, which is not covered in this document) which may make async API calls, schedule timers, or call process.nextTick(), then begins processing the event loop.
归纳出当一支Node程式执行时执行顺序
1. 初始化事件循环2. 同步任务3. 提出异步任务的请求4. 规划定时器的生效时间5. 执行process.nextTick()6. 开始事件循环
Node中异步任务有分本轮循环和次轮循环
这边你只要知道本轮循环一定比次轮循环还要早执行就对了。
上述的process.nextTick()
的回调(callback)是属于本轮循环的,千万不要被他的名词给骗去了(๑¯∀¯๑)
而除此之外还有微任务,就是指Promise
的回调函数(callback) ,他也是跟process.nextTick()的回调一样属于本轮循环。
然后他会在process.nextTick()的回调后执行。
而以下这些回调函数(callback)会加在次轮循环
setTimeoutsetIntervalsetImmediate
而Node中EventLoop分为六个阶段(如图)
而他们会依序执行图中的
1. timeers2. pending callbacks3. idlem prepare4. poll5. check6. close callbacks
然后他们各自是干嘛的?借用一下这篇的内容
各 Phase 的责任说明
timer:执行由 setTimeout() 及 setInterval() 排进来的 callbacks
I/O callbacks:有关系统错误等 Callbacks 将 queue 在此
idle, prepare:内部使用
poll:向系统取回新的 I/O 事件,执行对应的 I/O callbacks
check:执行由 setImmediate() 排进来的 callbacks
close callbacks:监听 I/O 'close' 事件的 callbacks (如 socket.on('close', ...))
看完上面的叙述应该会有一点点概念他执行顺序...
详细有兴趣可以自行再深入研究或底下留言讨论。想想上一篇浏览器的单纯时光,那是我逝去的青春
验收
看完以上来看看自己对于Node的同步和非同步执行顺序应该是略知一二了。
来验收看看啰
一样写下来看答案对不对~
console.log("A");setTimeout(() => console.log(1));console.log("B");setImmediate(() => console.log(2));console.log("C");process.nextTick(() => console.log(4));console.log("D");Promise.resolve().then(() => console.log(3));console.log("E");(() => console.log(5))();
答案
ABCDE5431 //有可能是22 //有可能是1
看完以上你应该会想说
靠北你还是没说为什么会有“可能是1可能是2的情况啊”
这边转贴一下别人的说明来源
这是因为setTimeout的第二个参数默认为0。但是实际上,Node 做不到0毫秒,最少也需要1毫秒,根据官方文档,第二个参数的取值范围在1毫秒到2147483647毫秒之间。也就是说,setTimeout(f, 0)等同于setTimeout(f, 1)。实际执行的时候,进入事件循环以后,有可能到了1毫秒,也可能还没到1毫秒,取决于系统当时的状况。如果没到1毫秒,那么 timers 阶段就会跳过,进入 check 阶段,先执行setImmediate的回调函数。
如果你没有想到
没关係
以上纯属开玩笑
不要告我
本週心得
我还是不要在每篇底下说我下篇要写什么好了xDD
每次立Flag,然后一直拆整篇的内容感觉很愧对各位大大 Orz
原本这篇要讲满多东西的但是这週有点忙直接拆了1/3
对不起QQ
参考文献
Banner设计
Node官方 Document
深入理解js事件循环机制(Node.js篇)
What is the different between JavaScript Event loop and Node.js Event loop?