什麼時候Node.js會進入事件循環?
发布于 8 年前 作者 byvoid 6788 次浏览 最后一次编辑是 4 年前

Node.js沒有像Ruby的EventMachine::run()一樣顯式進入事件循環的方法。什麼時候Node.js會進入事件循環呢?

例如

EventEmitter = require('events').EventEmitter;
ev = new EventEmitter();

ev.on('die', function() {
	console.log('done');
});

運行的話直接就結束了,如果後面再加一句 ev.emit(‘die’); ,就會進入消息循環。

setTimeout、http的listen都會讓Node.js進入事件循環,這些是怎麼實現的?還有那些,我自己如何實現?

8 回复

ev.emit(‘die’) 更像是多层函数嵌套调用

node的这个events不是底层事件,更像是自定义事件层

运行中的node进程,比如IO状态变更了,抛出一个事件, 这个事件的所有侦听被遍历执行,这个时候有可能触发另外一些事件,事件套事件,就像池塘里丢一个小石块一样,涟漪起来,事件处理完毕,又归于平静,等待下一个小石块。

逻辑上 事件是轮询判断生成的,底层事件(硬件中断信号,软件中断信号)应该也不例外。然后一层一层的向上层传递。

http的request等也是通过emit来执行事件的,不过那些并不止这么简单。通过Node.js源码可知,emit内部是同步执行的,所以会有阻塞问题,而http, fs等是通过底层的epoll把emit放进另外一个IO循环中,以达到异步的效果。

看代码,EventEmitter没有event loop,也没有参与event loop,只是一个注册、回调机制吧。

@WillWen:貌似regular fs用不了epoll,使用线程模拟的aio,是libeio与libev的联合使用:)

官方文档说用nextTick

手动进入事件循环?无限制process.nextTick()吧

当事件循环的引用计数大于0时就会进入循环,对应C++代码是

uv_ref(uv_default_loop());

你可以写一个C++ module来手动增加事件循环的引用计数

就是一个注册callback跟消息配对,然后emit的时候去回调相应的callback而已。emit这个函数应该是阻塞的。

事件循环是用在同步机制里面的。

回到顶部