为了处理以更加独立的方式发送到套接字的事件,我做了一个路由器。在该路由器中,我想将每个模块分配给特定事件。我已将事件字符串及其处理程序分配给“处理程序”对象。然后我想在循环中将侦听器分配给给定的套接字。在赋值之后,我列出了所有事件,并且给定套接字中的处理程序是清楚的。一切似乎都很好。不幸的是,它不起作用。 Socket就像它将处理程序对象中的每个事件分配给该对象中的第一个处理程序一样。手工制作的verion工作正常,但我不能理解为什么简单的循环失败:/
这是路由器的socketio处理套接字的代码:
var socketOptions = {transports:['flashsocket', 'websocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']};
var io = socketio.listen(server,socketOptions).on('connection', function (socket) {
streamRouter(io,socket);
});
这是路由器的代码。我写了如何看起来手工版本的分配套接字,以及如何看起来像环状verion。通常,第二个是评论。
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);
});
}
}
对于任何有关bug的建议,我都会很高兴。在很短的时间内,我将拥有许多处理程序,并逐个分配它们将是一个丑陋的复制粘贴代码:/
答案 0 :(得分:1)
在for-in
循环中,您构建的函数全部都在同一个event
变量上关闭。结果,当这些函数被执行时,它们都将引用相同的值。此外,您没有保护for-in
循环原型成员(可能是也可能没有)。
相反,试试这个:
Object.keys(handlers).forEach(function(event){
socket.on(event, function(msg){
handlers[event](io, socket, msg);
});
});
答案 1 :(得分:0)
要使循环起作用,您需要为每个处理程序创建一个新范围:
for( var event in handlers ) {
(function(handler) {
socket.on(event, function(msg){
handler(io,socket,msg);
});
})(handlers[event]);
}
这与范围有关:Javascript不会为每个循环创建一个“新的”event
变量,并且在调用事件处理程序时,event
将被覆盖(并且将会包含它在循环的最后一次迭代中所具有的值。
This page提供更多解释。