Node.js EventEmitter `on` 事件没有响应 `emit` 动作

Node.js EventEmitter `on` event is not responding to `emit` actions

我有一个代表 class 房间的 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。我尝试了几种变体,但没有任何运气。我做错了什么?

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

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

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

恕我直言,@Bhojendra Rauniyar 给出的答案是正确的,但缺少下面给出的工作示例。请注意,我在 student.js 中为 setTimeout() 定义回调函数时做了一个微妙但重要的更改:我正在使用箭头函数 () => 绑定学生实例的 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;