如何在Node.js的JavaScript模块文件之间使用事件处理程序?

我目前使用socket.io来发射和侦听客户端JavaScript文件和Node.js服务器文件之间的事件,但我希望能够发出和监听节点服务器和它的模块之间的事件。 我的想法是它看起来像这样:

节点服务器:

 var module1 = require('./module1'); //Some code to launch and run the server module1.emit('eventToModule'); module1.emit('moduleResponse', function(moduleVariable) { //server action based on module response } 

模块文件:

 var server = require('./server.js'); server.on('eventToModule', function() { //module response to server request } server.emit('moduleResponse', moduleVariable); 

这显然是一个简化的版本,但我认为这个function应该是可用的。 我是否需要将模块文件设置为第二台服务器? 如果是这样,那会是什么样子?

我也尝试使用var socket = io.connect('http://localhost:3000'); (这是我使用的代码,允许客户端连接到节点服务器)而不是server并让module1侦听module1送到socket但也没有工作。

第二次尝试(仍然不工作):

server.js

 //other requirements var module1 = require('./module'); const EventEmitter = require('events'); var emitter = new EventEmitter(); io.on('connection', function(client) { client.on('emitterTester', function() { emitter.emit('toModule'); emitter.on('toServer', function() { console.log("Emitter successful."); }); }); }); module.exports = emitter; 

module.js

 var server1 = require('./server'); const EventEmitter = require('events'); var emitter = new EventEmitter(); emitter.on('toModule', function() { console.log("Emitter heard by module."); emitter.emit('toServer'); }); module.exports = emitter; 

另外,当我尝试使用server1.on ,我得到消息server1.on is not a function

在node.js中,如果要创build具有事件侦听器并可以触发事件的对象,则通常使用EventEmitter对象 。 您可以直接使用EventEmitter对象,也可以从中派生出来并创build自己的具有所有EventEmitterfunction的对象。

所以,如果你想创build一个其他模块可以监听事件的模块,你可以这样做:

 // module1.js // module that has events // create EventEmitter object var obj = new EventEmitter(); // export the EventEmitter object so others can use it module.exports = obj; // other code in the module that does something to trigger events // this is just one example using a timer setInterval(function() { obj.emit("someEvent", someData); }, 10 * 1000); 

然后,你可以有另一个模块使用第一个模块,并侦听来自它的一些事件:

 // module2.js var m1 = require('module1.js'); // register event listener m1.on("someEvent", function(data) { // process data when someEvent occurs }); 

这里的关键是:

  1. 如果您希望模块允许人们监听事件并触发事件,那么您可能需要创build一个EventEmitter对象。
  2. 要共享该EventEmitter对象,可以将其分配给module.exportsmodule.exports一个属性,以便执行模块的require()的其他代码可以访问EventEmitter对象。
  3. 一旦调用代码从require()获得EventEmitter对象,它就可以注册来使用.on()方法来监听事件。
  4. 当原始模块或任何模块想要触发事件时,可以使用.emit()方法来实现。

请记住,有时事件是一个很好的架构select,但并不是所有模块之间的通信都最适合事件。 有时,只导出函数并允许一个模块调用另一个模块的函数是有意义的。 所以,事件并不是模块可以互相沟通的唯一方式。


你的问题似乎表明,你认为socket.io作为一个方式在同一个服务器进程中的两个模块进行通信。 虽然有可能做到这一点,但通常情况下不会使用socket.io。 通常,socket.io(基于TCP / IP)将用于在两个独立的进程之间进行通信,在这些进程中,您不必为进程中的事件直接调用函数或注册处理程序。 后两种scheme通常在一个进程中更容易进行通信,而socket.io则更典型地用于同一台计算机上的进程之间的通信或不同计算机上的进程之间的通信。