【问题标题】:node.js event listener in another source file另一个源文件中的 node.js 事件监听器
【发布时间】:2016-09-06 10:02:58
【问题描述】:

我正在尝试设计一个场景,在触发特定事件时,我希望一些侦听器执行某些任务。尝试同时管理代码的 S.R.P,我希望将侦听器放在不同的源文件中。我想知道这是否可以使用事件发射器。事件发射器是否仅适用于单个源文件?

var events = require('events');
var em = new events.EventEmitter();

exports.saveScheme = function (req, res) {  

var dal = dalFactory.createDAL(constants.SCHEME);
return new Promise.resolve(dal.PromiseSave(req.body))
    .then(function(data){
        var schemeId = data._id;

        em.addListener('FirstEvent', function (data) {
            console.log('First subscriber: ' + data);
        });
        em.emit('FirstEvent', 'Test event emitter');

    }).catch(function(error){
        console.log(error);
    }); 
};

我的另一个源文件是

var emitter = require('events').EventEmitter;
var em = new emitter();

//Subscribe FirstEvent
em.on('FirstEvent', function (data) {
    console.log('First subscriber: ' + data);
});

【问题讨论】:

    标签: node.js event-handling eventemitter


    【解决方案1】:

    您创建的每个 eventEmitter 对象都是一个新实例,因此从第一个触发的事件不会在第二个触发,因此您的问题的答案是 - 不,这是不可能的。 但是,还有其他解决方案:

    我认为最好的方法是创建一个集中的公共 eventEmitter,如下所示:

    //firstFile.js
    var common = require('./common');
    var commonEmitter = common.commonEmitter;
    
    exports.saveScheme = function (req, res) {  
    
    var dal = dalFactory.createDAL(constants.SCHEME);
    return new Promise.resolve(dal.PromiseSave(req.body))
        .then(function(data){
            var schemeId = data._id;
    
            commonEmitter.addListener('FirstEvent', function (data) {
                console.log('First subscriber: ' + data);
            });
            commonEmitter.emit('FirstEvent', 'Test event emitter');
    
        }).catch(function(error){
            console.log(error);
        }); 
    };
    
    
    
    //secondFile.js
    var common = require('./common');
    var commonEmitter = common.commonEmitter;
    
    //Subscribe FirstEvent
    commonEmitter.on('FirstEvent', function (data) {
        console.log('First subscriber: ' + data);
    });
    
    
    //common.js
    var events = require('events');
    var em = new events.EventEmitter();
    module.exports.commonEmitter = em;
    

    但是,如果您希望源文件彼此“了解” - 您可以执行以下操作:

    //firstFile.js
    var events = require('events');
    var em = new events.EventEmitter();
    
    exports.saveScheme = function (req, res) {  
    
    var dal = dalFactory.createDAL(constants.SCHEME);
    return new Promise.resolve(dal.PromiseSave(req.body))
        .then(function(data){
            var schemeId = data._id;
    
            em.addListener('FirstEvent', function (data) {
                console.log('First subscriber: ' + data);
            });
            em.emit('FirstEvent', 'Test event emitter');
    
        }).catch(function(error){
            console.log(error);
        }); 
    };
    exports.emitter = em;
    
    
    
    //secondFile.js
    var firstFile = require('./firstFile');
    var firstFileEmitter = firstFile.emitter;
    
    //Subscribe FirstEvent
    firstFileEmitter.on('FirstEvent', function (data) {
        console.log('First subscriber: ' + data);
    });
    

    【讨论】:

    • 非常感谢您的洞察力。
    • 嗨 Gilad,我尝试了示例 2,我创建了 2 个没有任何逻辑的 js 文件,只是做了和 em.emit 并做了一个 export.emitter。在第二个文件中我没有做任何更改。第二个文件的 console.log 没有被调用。关于我错过了什么的任何想法
    • 您能否以某种方式附上您的代码(作为评论或新问题)?
    • 我无法将其放入评论中,因此我将其添加为下面的答案
    【解决方案2】:

    事件监听器和发射器可以在两个不同的文件中。请看下面一个简单的例子:

    第一个文件,我们称之为eventEx.js

     var EventEmitter = require('events').EventEmitter
    
       var myEmitter = new EventEmitter();
    
       myEmitter.on('print', (arg) => {
        console.log(arg);
       })
    
       exports.myEmitter = myEmitter
    

    第二个文件如下:

    var emitter = require('./eventEx.js')
    var printEmitter = emitter.myEmitter
    
    printEmitter.emit('print', 'how was Dunkirk?')
    printEmitter.emit('print', 'Dunkirk was awesome!!')
    

    【讨论】:

    • 但是你在另一个文件中导入了eventex,解决办法是有2个文件不相互导入但两者之间有共同的eventemitter,这可能吗
    【解决方案3】:

    这就是我在测试中使用的方式。我将它与类语义一起使用

    需要注意的一点是,在发出事件之前总是需要注册一个监听器,因为当一个事件被发出时,它会寻找已经注册的一组监听器,然后在那里发出流。

    //emitter.js
    // The core module events has EventEmitter class which we are going to make use of
    // note that we are not going to use that explicitly but by means of another class
    
    const EventEmitter = require('events');
    
    Class EventEmitterClass extends EventEmitter{
        emitterMethod(){
          this.emit('testEventEmitted', {obj:'testString object'});
        }
    }
    
    module.exports = EventEmitterClass; // we export the module with the objectInstance
    
    //listener.js
    // now import the emitter.js and we get back a class - EventEmitterClass
    const EventEmitterClass = require('./emitter.js');//give the actual path of js
    const eventEmitterObj = new EventEmitterClass();
    
    //now it is mandatory to register the listener before we even think of calling the //emitter method
    eventEmitterObj.addListener('testEventEmitted', res => {
       console.log('this is the result from the emitted event:', res);
    });
    
    //now call the method that emits the event in the class
    eventEmitterObj.emitterMethod();
    

    现在运行listener.js -> node listerner.js

    抱歉,如果我解释得太详细了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      • 2020-06-24
      • 2018-05-16
      • 1970-01-01
      • 2011-06-22
      • 2021-03-17
      相关资源
      最近更新 更多