【问题标题】:How do I use event handlers between JavaScript module files with Node.js?如何在带有 Node.js 的 JavaScript 模块文件之间使用事件处理程序?
【发布时间】:2016-09-11 03:03:35
【问题描述】:

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

节点服务器:

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);

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

我还尝试使用var socket = io.connect('http://localhost:3000');(这是我用来允许客户端连接到节点服务器的代码)而不是server,并让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;

模块.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

【问题讨论】:

    标签: javascript node.js sockets module


    【解决方案1】:

    在 node.js 中,EventEmitter object 通常是您想要创建具有事件侦听器并随后可以触发事件的对象时使用的。您可以直接使用EventEmitter 对象,也可以从它派生并创建自己的具有所有EventEmitter 功能的对象。

    因此,如果您想创建一个其他模块可以监听事件的模块,您可以执行以下操作:

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

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


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

    【讨论】:

    • 感谢您的回复,但它仍然不适合我。我编辑了原始帖子以显示我尝试的第二件事。顺便说一句,我知道我可以通过导入方法并在服务器文件中使用它们来设置它。我更喜欢通过事件来减少服务器文件的大部分。谢谢。
    • @SuperCodeBrah - 您没有完全显示足够的代码(我们需要在 server.js 中查看 module.exports),但您似乎没有从 server.js 导出 EventEmitter 然后使用它module.js 中的特定 eventEmitter 实例。请看我的代码示例是如何做到的。
    • 是的,我在第一次编辑时错过了。应该是现在。此外,事件在服务器和模块之间是双向的,所以我认为无论我在模块中有什么,我都需要在服务器中,反之亦然。
    • @SuperCodeBrah - 您可以使用一个事件发射器并让每一侧发射到该事件并监听不同的事件,或者每一侧都可以导出自己的发射器 - 这真的取决于。如果这现在回答了您的问题,您可以选中答案左侧的绿色复选标记,向社区表明这一点,并通过遵循正确的程序为自己赢得一些声誉。
    • 您没有在正确的发射器上调用.emit()。由于您正在创建两个发射器,因此您需要在另一个发射器(另一个模块正在侦听的那个)上调用 .emit()。在 module.js 中,将 emitter.emit('toServer'); 更改为 server1.emit('toServer'); 并在 server.js 中进行相应更改。我还看到您在这里有一个循环依赖关系,其中每个模块都需要另一个模块并在其初始化中使用模块句柄 - 我不太确定 node.js 如何处理它。
    【解决方案2】:

    为了方便我,我创建了一个名为 Notifier.js 的新 js 文件,如下所示:

    let EventEmitter = require('events').EventEmitter
    let notifier = new EventEmitter()
    module.exports = notifier
    

    当我想使用发射器时,我只需要Notifier.js 文件并访问导出的值。例如

    randomFile.js

    var notifier = require('Notifier.js')
    notifier.on('myEvent', (message) => {
        console.log(message)
    })
    

    randomFile2.js

    var notifier = require('Notifier.js')
    notifier.emit('myEvent', 'Test Message')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-19
      • 1970-01-01
      • 2012-04-17
      • 2019-10-28
      • 2022-08-13
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      相关资源
      最近更新 更多