"Extend" THE EventEmitter tak:
var EventEmitter = require('events').EventEmitter;
EventEmitter.prototype.once = function(events, handler){
// no events, get out!
if(! events)
return;
// Ugly, but helps getting the rest of the function
// short and simple to the eye ... I guess...
if(!(events instanceof Array))
events = [events];
var _this = this;
var cb = function(){
events.forEach(function(e){
// This only removes the listener itself
// from all the events that are listening to it
// i.e., does not remove other listeners to the same event!
_this.removeListener(e, cb);
});
// This will allow any args you put in xxx.emit('event', ...) to be sent
// to your handler
handler.apply(_this, Array.prototype.slice.call(arguments, 0));
};
events.forEach(function(e){
_this.addListener(e, cb);
});
};
I stworzył istotę tutaj: https://gist.github.com/3627823 który zawiera przykład (twój przykład, z pewnymi logami)
[UPDATE] Fol ryk jest adaptacją mojego wykonania once
że usuwa tylko zdarzenie, które nazwano, zgodnie z wnioskiem w komentarzach:
var EventEmitter = require('events').EventEmitter;
EventEmitter.prototype.once = function(events, handler){
// no events, get out!
if(! events)
return;
// Ugly, but helps getting the rest of the function
// short and simple to the eye ... I guess...
if(!(events instanceof Array))
events = [events];
var _this = this;
// A helper function that will generate a handler that
// removes itself when its called
var gen_cb = function(event_name){
var cb = function(){
_this.removeListener(event_name, cb);
// This will allow any args you put in
// xxx.emit('event', ...) to be sent
// to your handler
handler.apply(_this, Array.prototype.slice.call(arguments, 0));
};
return cb;
};
events.forEach(function(e){
_this.addListener(e, gen_cb(e));
});
};
I okazało się, że node.js ma już once
metody w EventEmitter: sprawdź here the source code, ale jest to prawdopodobnie ostatni dodatek.
To faktycznie łamie 'removeListener' z pracy jak to wcześniej zrobił. Może ta odpowiedź może zostać rozszerzona, aby to naprawić. – Harry
Czy chcesz, aby 'removeListener' usuwał tylko wywoływane zdarzenie, zamiast wszystkich zdarzeń, które są wysyłane jako argumenty' events'? Jak tylko zorientuję się, czego chcesz, zaktualizuję odpowiedź. – fableal
Po prostu wydarzenie, które zostało wysłane, byłoby wspaniałe. – Harry