【问题标题】:event handler that knows the event name知道事件名称的事件处理程序
【发布时间】:2013-05-02 11:16:46
【问题描述】:

我有一个生成许多事件的 socket.io 服务器,我想捕获所有事件并打印类似的消息。现在,我这样做:

for (var event in {eventA: 1, eventB: 1, eventC: 1}) {
    this.translationSocket.on(event, function(result) {
        console.log("Server sent an event of type "+event);
    });
}

当服务器发送 eventA、eventB 和 eventC 时,我看到了这个:

Server sent an event of type eventC
Server sent an event of type eventC
Server sent an event of type eventC

即我的程序捕获所有事件,但始终显示 eventC 的类型...

我尝试了以下变体:

  • 去掉“for”中“event”前的“var”:“for (event ...”
  • 添加语句'var msg = "服务器发送了一个类型为"+event;'的事件在“on”语句之前或在“console.log”语句之前,然后是“console.log(msg)”。

这些变化都不起作用...

我该怎么办?

【问题讨论】:

    标签: javascript asynchronous scope


    【解决方案1】:

    这与 socket.io 或 node.js 无关,这是众所周知的 JavaScript “怪癖”。 event 的值是在代码执行时评估的,也就是循环结束的时候。您需要将事物包装到函数调用中以保留该值。

    var listen = function(socket, event) {
        socket.on(event, function(result) {
            console.log("Server sent an event of type "+event);
        });
    }
    
    
    for (var event in {eventA: 1, eventB: 1, eventC: 1}) {
        listen(event);
    }
    

    或者(较短的版本):

    for (var event in {eventA: 1, eventB: 1, eventC: 1}) {
        (function(event) {
            this.translationSocket.on(event, function(result) {
                console.log("Server sent an event of type "+event);
            });
        })(event);
    }
    

    【讨论】:

      【解决方案2】:

      for (var event in ...) 中,您声明了一个变量,并且由于 JavaScript 中的变量范围规则,它将在 foreach 循环之外有效。

      event 变量在循环结束时变为eventC。 所以它的价值,当你想打印它会eventC

      你可以这样做:

      function generateCallback(e, result) {
          return function () {
              console.log("Server sent an event of type " + e);
          };
      }
      
      var e;
      // ...
      for (e in {eventA: 1, eventB: 1, eventC: 1}) {
          this.translationSocket.on(e, generateCallback(e, result));
      }
      

      为了防止混淆you'd better not to declare variables in for statements

      而且更好,not to make functions within a loop。这就是为什么我使用generateCallback 而不是在循环中创建回调函数的原因。

      【讨论】:

      • 谢谢,这个“var”问题真的很混乱。
      【解决方案3】:

      我会在 npm 上使用 socket.io-events。您可以捕获所有事件并根据需要处理它们,而无需绑定单独的处理程序。

      var io = require('socket.io')(3000);
      var router = require('socket.io-events')();
       router.on('*', function (sock, args, next) {
       var name = args.shift(), msg = args.shift();
       sock.emit('received event', name, msg);
      });
      io.use(router);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-25
        相关资源
        最近更新 更多