javascript eventemitter多次事件一次 [英] javascript eventemitter multiple events once

查看:163
本文介绍了javascript eventemitter多次事件一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using node's eventemitter though other event library suggestions are welcomed.

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

I want to run a function once if several events are fired. Multiple events should be listened to, but all of them are removed if any one of the events fires. Hopefully this code sample demonstrates what I'm looking for.

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

最简单的处理方式是什么?

What is the cleanest way to handle this?

注意:需要单独删除绑定函数,因为会绑定其他侦听器。

Note: Need to remove bound functions individually because there will be other listeners bound.

推荐答案

扩展EventEmitter就像这个:

"Extend" the EventEmitter like this:

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
其中包含一个示例(您的示例,包含一些日志)

I created a gist here: https://gist.github.com/3627823 which includes an example (your example, with some logs)

[ UPDATE ]
以下是我的实现的改编,它只删除被调用的事件,如评论中要求:

[UPDATE] Following is an adaptation of my implementation of once that removes only the event that was called, as requested in the comments:

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已经有一次方法:检查这里的源代码,但这可能是最近添加的。

I found out that node.js already has a once method in the EventEmitter: check here the source code, but this is probably a recent addition.

这篇关于javascript eventemitter多次事件一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆