2016-10-02 2 views
5

Gibt es eine Möglichkeit, auf den Klassenkontext in der Event-Listener-Methode mit der Möglichkeit zuzugreifen, den Listener zu entfernen?Node.js EventEmitter: Wie binden Sie einen Klassenkontext an den Ereignis-Listener und entfernen diesen Listener dann

Beispiel 1:

import {EventEmitter} from "events"; 

export default class EventsExample1 { 
    private emitter: EventEmitter; 

    constructor(private text: string) { 
     this.emitter = new EventEmitter(); 

     this.emitter.addListener("test", this.handleTestEvent); 
     this.emitter.emit("test"); 
    } 


    public dispose() { 
     this.emitter.removeListener("test", this.handleTestEvent); 
    } 

    private handleTestEvent() { 
     console.log(this.text); 
    } 
} 

In diesem Beispiel arbeitet die Zuhörer zu entfernen, aber die handleTestEvent() Methode hat keinen Zugriff auf die Kontextklasse this verwenden. this verweist auf EventEmitter-Kontext, daher ist this.text nicht verfügbar.

Beispiel 2:

import {EventEmitter} from "events"; 

export default class EventsExample2 { 
    private emitter: EventEmitter; 

    constructor(private text: string) { 
     this.emitter = new EventEmitter(); 

     this.emitter.addListener("test", this.handleTestEvent.bind(this)); 
     this.emitter.emit("test"); 
    } 

    public dispose() { 
     this.emitter.removeListener("test", this.handleTestEvent); 
    } 

    private handleTestEvent() { 
     console.log(this.text); 
    } 
} 

In diesem Beispiel verwendet ich die bind Funktion einen Zusammenhang mit der Klasse zu dem Ereignis-Listener zu binden. Jetzt handleTestEvent Methode hat Zugriff auf den Klassenkontext mit this =>this.text ist zugänglich, aber Listener kann nicht mit removeListener entfernt werden - es scheint, dass bind erstellt eine neue anonyme Funktion, so dass es keinen Verweis auf den gebundenen Listener gibt.

Beispiel 3:

import {EventEmitter} from "events"; 

export default class EventsExample3 { 
    private emitter: EventEmitter; 

    constructor(private text: string) { 
     this.emitter = new EventEmitter(); 

     this.emitter.addListener("test",() => this.handleTestEvent()); 
     this.emitter.emit("test"); 
    } 

    public dispose() { 
     this.emitter.removeListener("test", this.handleTestEvent); 
    } 

    private handleTestEvent() { 
     console.log(this.text); 
    } 
} 

In diesem Beispiel verwende ich eine Pfeil Funktion einen Zusammenhang mit der Klasse in dem Ereignis-Listener zu bewahren. handleTestEvent Methode hat Zugriff auf den Klassenkontext mit this, aber Listener kann nicht entfernt werden (es gibt keinen Verweis auf den begrenzten Listener wie in Beispiel 2).

Ich habe eine alternative Veranstaltung Bibliothek versucht - EventEmitter3 die für Veranstaltungen (Klassenkontext kann eine Unterstützung für benutzerdefinierten Kontext hat als dritten Parameter an die Funktion addListener (this.emitter.addListener("test", this.handleTestEvent, this) übergeben werden, es funktioniert perfekt, aber ich mag lieber verwenden die mitgelieferte EventEmitter von Node.js.

Antwort

4

Sie dies im Konstruktor tun könnte:

this.handleTestEvent = this.handleTestEvent.bind(this); 
this.emitter.addListener("test", this.handleTestEvent); 

Wenn Sie Schneide verwenden möchten, können Sie die proposed bind operator als Abkürzung verwenden:

this.handleTestEvent = ::this.handleTestEvent; 
this.emitter.addListener("test", this.handleTestEvent); 

Oder eine property initializer verwenden, um eine gebundene Methode erstellt werden:

constructor(private text: string) { 
    this.emitter = new EventEmitter(); 

    this.emitter.addListener("test", this.handleTestEvent); 
    this.emitter.emit("test"); 
} 

handleTestEvent =() => { 
    console.log(this.text); 
} 
0

du wahrscheinlich aussortiert, aber sie hätte nur

getan
import {EventEmitter} from "events"; 

class HasEvents extends EventEmitter {} 

const emitter = new HasEvents(); 
Verwandte Themen