2013-04-11 72 views
0

處理事件發送到插座更orginased的方式,我做了一個路由器。在該路由器中,我想將每個模塊分配給特定的事件。我已將事件字符串及其處理程序分配給「處理程序」對象。然後我想在一個循環中將偵聽器分配給給定的套接字。在賦值之後,我列出了所有事件,並且它在給定套接字中的處理程序清楚。一切似乎都很好。不幸的是,它不起作用。套接字的行爲就像它將處理程序對象中的每個事件分配給該對象中的第一個處理程序。手工優化版本工作正常,但我只是不能得到它,爲什麼簡單的循環失敗:/添加處理程序,在循環不工作插座:/

這裏是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); 
     }); 
    } 
} 

對於任何有關錯誤的建議,我都會很樂意。在很短的時間內,我將有許多處理程序,並將它們逐一分配,這將是一段很難複製的代碼行:/

回答

1

在你for-in循環,你就構造被全部封閉在同一event變量函數。因此,當這些函數被執行時,它們都會引用相同的值。此外,你不守着你for-in對原型成員循環(這可能會或可能不會意)。

相反,試試這個:

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

感謝球員,你的答案wehere非常有用的。它像一個魅力。 – 2013-04-11 09:26:10

0

要使循環正常工作,需要爲每個處理程序創建一個新的作用域:

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

這有做的作用域:JavaScript不爲每個迴路一個「新」 event變量,並通過事件處理程序被調用的時候,event將被覆蓋(幷包含值它在循環的最後一次迭代中)。

This page提供了更多的解釋。