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進入事件循環,這些是怎麼實現的?還有那些,我自己如何實現?
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这个函数应该是阻塞的。
事件循环是用在同步机制里面的。