像这样“扩展” EventEmitter:
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);
});
};
我在这里创建了一个要点:https ://gist.github.com/3627823
其中包括一个示例(您的示例,带有一些日志)
[更新]以下是我的实现的改编,once
它只删除了被调用的事件,如评论中所要求的:
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));
});
};
我发现 node.js 已经once
在 EventEmitter 中有一个方法:查看这里的源代码,但这可能是最近添加的。