向套接字循环中添加处理程序不起作用:/



为了更有组织地处理发送到套接字的事件,我制作了一个路由器。在该路由器中,我想将每个模块分配给特定的事件。我已经将事件字符串及其处理程序分配给"处理程序"对象。然后我想在循环中为给定的套接字分配侦听器。赋值后,我列出了给定套接字中的所有事件及其处理程序。一切似乎都很好。不幸的是,它不起作用。套接字的行为就像它会将处理程序对象中的每个事件分配给该对象中的第一个处理程序。手工版本工作得很好,但我就是不明白为什么简单的循环失败:/

下面是路由器处理socket的代码:

var socketOptions = {transports:['flashsocket', 'websocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']};
var io = socketio.listen(server,socketOptions).on('connection', function (socket) {
    streamRouter(io,socket);
});

这是路由器的代码。我已经写了手工版本的套接字分配和它看起来像循环版本。一般情况下,第二个会被注释。

var handlers = {
    "message": require("./message").doAction,
    "subscribe": require("./subscribe").doAction
}
exports.handleConnection = function(io,socket) {
    //handmade version
    socket.on("subscribe", function(msg){
           require("./subscribe").doAction(io,socket,msg);
    });
    socket.on("message", function(msg){
           require("./message").doAction(io,socket,msg);
    });
    //loop version
    for( var event in handlers ) {
        socket.on(event, function(msg){
           handlers[event](io,socket,msg);
        });
    }
}
如果你能告诉我错误在哪里,我将不胜感激。在很短的时间内,我将有许多处理程序,逐个分配它们将是通过许多行代码进行丑陋的复制粘贴:/

在您的for-in循环中,您正在构建对同一event变量闭合的函数。因此,当这些函数执行时,它们都指向相同的值。此外,你没有保护你的for-in循环不受原型成员的影响(这可能是也可能不是有意的)。

不如试试这样:

Object.keys(handlers).forEach(function(event){
    socket.on(event, function(msg){
        handlers[event](io, socket, msg);
    });
});

要让循环工作,你需要为每个处理程序创建一个新的作用域:

for( var event in handlers ) {
  (function(handler) {
    socket.on(event, function(msg){
      handler(io,socket,msg);
    });
  })(handlers[event]);
}

这与作用域有关:Javascript不会为每个循环创建一个"新的"event变量,并且在调用事件处理程序时,event将被覆盖(并且将包含它在循环的最后一次迭代中的值)。

相关内容

最新更新