0

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

这是路由器通过socketio处理套接字的代码:

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);
        });
    }
}

对于错误所在的任何建议,我将不胜感激。在短时间内,我将拥有许多处理程序,并且通过多行代码一一分配它们将是一种丑陋的复制粘贴:/

4

2 回答 2

1

In your for-in loop, you're constructing functions that are all closed over the same event variable. As a result, when those functions get executed, they will all refer to the same value. Additionally, you're not guarding your for-in loop against prototype members (which may or may not be intended).

Instead, try this:

Object.keys(handlers).forEach(function(event){
    socket.on(event, function(msg){
        handlers[event](io, socket, msg);
    });
});
于 2013-04-11T09:16:16.473 回答
0

为了使循环正常工作,您需要为每个处理程序创建一个新范围:

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

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

此页面提供了更多解释。

于 2013-04-11T09:14:48.633 回答