Javascript eventemitter 多个事件一次

标签 javascript node.js dom-events eventemitter

我正在使用 Node 的 eventemitter 虽然欢迎其他事件库建议。

如果触发了多个事件,我想运行一次函数。应该监听多个事件,但如果任何一个事件触发,它们都会被删除。希望此代码示例演示了我正在寻找的内容。

var game = new eventEmitter();
game.once(['player:quit', 'player:disconnect'], function () {
  endGame()
});

最干净的处理方法是什么?

注意:需要单独移除绑定(bind)的函数,因为还会绑定(bind)其他监听器。

最佳答案

像这样“扩展”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 在 EventEmitter 中已经有一个 once 方法:检查 here the source code ,但这可能是最近添加的。

关于Javascript eventemitter 多个事件一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12150540/

相关文章:

javascript - 我在DOM中看到了element,但是在页面上没有看到他。 WP插件Jet菜单

node.js - 检查文件是否存在于我的服务器上 - Node js

javascript - 而鼠标按下事件。原型(prototype) JS 或 Javascript

javascript - 如何为一个页面上的多个谷歌地图添加DomListener?

javascript - (揭示)模块模式、公共(public)变量和返回语句

javascript - Web Audio API 如何修改混响尾音、房间大小和其他环境变量

javascript - 如何将数组缓冲区数据与字符串/json 一起发送到 NodeJS 服务器

node.js - connect.cookieParser 和 connect.session

javascript - 什么时候调用 "DOMNodeInserted"事件?

javascript - 使用 JavaScript 在 Onblur 事件的下拉菜单中选择选项