节点 js 事件侦听器未按预期工作

Node js event listener not working as expected

所以我基本上是在尝试在不同的打字稿 classes 上发出和收听特定事件。发出的第一个事件在另一个 class 上被正确监听,但是一旦我设置超时以在 10 秒后发出其他事件,例如,它就像监听器不再监听..

commonEmitter.ts

let events = require('events');
let em = new events.EventEmitter();
module.exports.commonEmitter = em;

network.ts

export class Network {

  constructor() {
    this.setConnection('connected');

    setTimeout(() => {
      commonEmitter.emit('connectionStatusChanged');
      connection = 'disconnected';
    }, 10000);
  }

private setConnection(newConnection): void {
      connection = newConnection
      commonEmitter.emit('connectionStatusChanged');
}

public isConnected(): boolean {
    return connection === 'connected';
}

}

export let connection = null;

view.ts

export class View {

private network: any;

constructor() { }


private test(){
   console.log('Online? ' + this.network.isConnected());
}

public init(){

commonEmitter.on('connectionStatusChanged', this.test());

this.network = new Network();

}

最后,两个事件都发出了,但只有第一个发出 "listened"。 这样做的原因是什么?我该如何有序地进行?

在这行代码中:

commonEmitter.on('connectionStatusChanged', this.test()); 

您正在立即调用 this.test(),而不是传递可以稍后调用的函数引用。将其更改为:

commonEmitter.on('connectionStatusChanged', this.test.bind(this)); 

因此,您正确传递了一个函数引用,该引用也将正确绑定到 this


或者,您可以使用粗箭头回调函数来保留 this 的词法值,如下所示:

commonEmitter.on('connectionStatusChanged', () => {
    this.test();
}); 

箭头函数与测试函数调用相结合对我有用,非常感谢@jfriend000 :p 带有绑定方法的函数不起作用,但没关系。

我还有一个问题,每次我尝试使用任何类型的参数发出和事件时,听众都没有听到。例如:

// view.ts
commonEmitter.on('connectionStatusChanged', (data: boolean) => {
   console.log(data);
}); 

// network.ts
commonEmitter.emit('connectionStatusChanged', true);

如果这也跟语境有关,应该怎么办?

要回答第二个问题,您应该将对象作为参数传递给 emit

// network.ts
commonEmitter.emit('connectionStatusChanged', {data: true});

通过使用这个解决方案,现在从网络 class 发出的第一个事件永远不会被监听。只有在超时之后它才会工作并刷新视图,但我不知道为什么第一个不:/

// network.ts

commonEmitter.emit('connectionStatusChanged', {isOnline: true});

// view.ts

commonEmitter.on('connectionStatusChanged', (data: any) => {
      console.log('Online? ' + data.isOnline);
});