"Estendere" l'EventEmitter in questo modo:
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);
});
};
ho creato un succo qui: https://gist.github.com/3627823 che include un esempio (il tuo esempio, con alcuni registri)
[UPDATE] Fol muggito è un adattamento della mia implementazione di once
che rimuove solo l'evento che è stato chiamato, come richiesto nei commenti:
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));
});
};
ho scoperto che node.js ha già il metodo once
nella EventEmitter: controllare here the source code, ma questa è probabilmente un'aggiunta recente.
Questo in realtà si rompe 'removeListener' di lavorare come in precedenza ha fatto. Forse questa risposta potrebbe essere espansa per risolverlo. – Harry
Vuoi 'removeListener' per rimuovere solo l'evento che è stato chiamato, invece di tutti gli eventi inviati come argomento' events'? Appena avrò un'idea di quello che vuoi, aggiornerò la mia risposta. – fableal
Solo l'evento inviato sarebbe fantastico. – Harry