【问题标题】:Node.js EventEmitter `on` event is not responding to `emit` actionsNode.js EventEmitter `on` 事件没有响应 `emit` 动作
【发布时间】:2019-03-16 12:14:08
【问题描述】:

我有一个代表教室的 Node.js 应用程序。我使用的是节点版本 11.11.0。这个应用程序有两个文件:index.js 和 student.js。相关代码如下所示:

index.js

const EventEmitter = require('events');
const Student = require('./student');

async function start() {
  eventEmitter.on('newListener', (event, listener) => {
     console.log(`Added ${event} listener.`);
  });

  eventEmitter.on('handRaised', (question) => {
    console.log(question);
  });

  for (let i=0; i<10; i++) {
    let student = new Student(`Student #${i+1}`);
    student.attend();
  }
}

start();

student.js

'use strict';

const EventEmitter = require('events');

class Student {
  constructor(name) {
    this.name = name;
  }

  attend() {
    // simulate a student randomly asking a question within 10 minutes
    let minutes = (Math.floor(Math.random() * 10) + 1) * 60000;
    setTimeout(function() {
      EventEmitter.emit('handRaised', 'What is the 2 + 3?');
    }, minutes);
  }
}

module.exports = Student;

当我运行它时,我收到一个错误,上面写着EventEmitter.emit is not a function。我已经尝试了几种变体,但没有任何运气。我做错了什么?

【问题讨论】:

    标签: javascript node.js eventemitter


    【解决方案1】:

    您不能直接在EventEmitter 上使用emit。你需要有它的一个实例。例如:

    const eventEmitter = new EventEmitter();
    // Now, you're okay to go with emit
    eventEmitter.emit('handRaised', 'What is the 2 + 3?');
    

    要使用相同的实例,请将其定义在一个文件中,并在需要它的任何地方使用它。然后,您可以安全地使用onemit

    【讨论】:

      【解决方案2】:

      @Bhojendra Rauniyar 给出的答案是正确的,恕我直言,但缺少下面给出的工作示例。请注意,我为在student.js 中定义setTimeout() 的回调函数做了一个微妙但重要的更改:我正在使用箭头函数() =&gt;,它将学生实例的this 绑定到回调函数。这是从回调函数调用实例变量所必需的。或者可以使用function () { ... }.bind(this)

      index.js

      const EventEmitter = require('events');
      const Student = require('./student');
      const eventEmitter = new EventEmitter();
      
      async function start() {
        eventEmitter.on('newListener', (event, listener) => {
          console.log(`Added ${event} listener.`);
      });
      
        eventEmitter.on('handRaised', (question) => {
          console.log(question);
      });
      
        for (let i=0; i<10; i++) {
          let student = new Student(`Student #${i+1}`, eventEmitter);
          student.attend();
        }
      }
      
      start();
      

      student.js

      'use strict';
      
      class Student {
        constructor(name, eventEmitter) {
          this.name = name;
          this.eventEmitter = eventEmitter;
        }
      
        attend() {
          // simulate a student randomly asking a question within 10 minutes
          let minutes = (Math.floor(Math.random() * 10) + 1) * 60000;
          setTimeout(() => {
            this.eventEmitter.emit('handRaised', 'What is the 2 + 3?');
        }, minutes);
        }
      }
      
      module.exports = Student;
      

      【讨论】:

      • 太棒了!我错过了我需要将 eventEmitter 从教室传递给学生对象的事实。我认为 EventEmitter 是某种全球消息传递系统。
      • 另一种方法是从 EventEmitter 派生类“Student”,并让管理代码在每个 Student 实例上注册一个侦听器。请参阅以下线程以获取示例 stackoverflow.com/questions/38280844/…
      • @SomeUser 实现了您可以使用Dependency Injection 模式,并定义一个扩展EventEmitter 的全局event manager 并将其注入到所有需要EventEmitter 功能的类中。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 2014-09-03
      • 2017-11-12
      相关资源
      最近更新 更多