Javascript 将函数绑定到多个套接字
假设第四个插座连接时,Javascript 将函数绑定到多个套接字,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,假设第四个插座连接时,条件为真。下面的代码成功地将.on处理程序绑定到myRoom中的所有套接字 io.on('connection', function(socket) { socket.join('myRoom'); if(condition){ bindFunctions(); } }); 但是,当'my event'触发时,无论是哪个客户端触发了它,socket对象始终是连接的第四个套接字。调用bindFunctions的总是套接字。我认为处
条件
为真。下面的代码成功地将.on
处理程序绑定到myRoom
中的所有套接字
io.on('connection', function(socket) {
socket.join('myRoom');
if(condition){
bindFunctions();
}
});
但是,当'my event'
触发时,无论是哪个客户端触发了它,socket
对象始终是连接的第四个套接字。调用bindFunctions
的总是套接字。我认为处理程序套接字应该与函数中的套接字相同
所以我有两个问题:
为什么'my event'
函数中的套接字是调用bindFunctions
的套接字,而不是触发事件的套接字
我可以做些什么来代替在函数内部访问调用“我的事件”的套接字的属性?这是因为尽管您正在执行
var socket=io.sockets.connected[socketId]代码>在循环内,且不在块范围内
在勇气之下,真正发生的是:
bindFunctions(){
for(var socketId in io.sockets.adapter.rooms["myRoom"]){
var socket = io.sockets.connected[socketId];
socket.on('my event',function(submit){
console.log(socket.myVariable);
//This is always the same property, no matter who calls this function.
});
}
}
因此,由于事件将在稍后发生,因此socket
变量始终是最后一组
为了防止这种行为,如果使用Node.js version>4.0.0,可以使用。但是在Node.js中,为了能够使用const
和let
关键字阻塞范围,必须将设置为“使用严格”代码>在函数的开头,例如:
bindFunctions(){
var socket;
for(var socketId in io.sockets.adapter.rooms["myRoom"]){
socket = io.sockets.connected[socketId];
socket.on('my event',function(submit){
console.log(socket.myVariable);
//This is always the same property, no matter who calls this function.
});
}
}
解决问题的另一种方法是创建IIFE,因此始终将当前变量传递给事件,例如:
bindFunctions(){
'use strict';
for(var socketId in io.sockets.adapter.rooms["myRoom"]){
const socket = io.sockets.connected[socketId];
socket.on('my event',function(submit){
console.log(socket.myVariable);
//This is always the same property, no matter who calls this function.
});
}
}
这样,IIFE中的socket
变量将始终引用作为参数传递的对象,您将获得所需的行为
您还可以将Object.keys
与Array.prototype.forEach
结合使用,而不是用于循环中的…:
bindFunctions(){
for(var socketId in io.sockets.adapter.rooms["myRoom"]){
var socket = io.sockets.connected[socketId];
(function(socket) {
socket.on('my event',function(submit){
console.log(socket.myVariable);
});
})(socket);
}
}
这样,每次迭代都会创建一个新的上下文,因为它是一个被调用的回调函数,并且在函数作用域方面不会有问题。为什么不在函数连接后直接将其绑定到套接字?比如io.on('connection',function(socket){socket.join('myroom');socket.on('myevent',function…)
然后你可以检查绑定函数内的条件……这样你就不必在套接字上循环。可能最好使用让,不?const
不是代表一个不变的变量吗?@JonathanBrooks因为他在循环内创建套接字
,并且从不改变它,理论上是一个变量const
变量。如果您使用一些linter,例如:ESLint,它将发出警告,尽管您使用的是let
,但您永远不会更改它的值。非常感谢@Buzinas:)还有,有关“变量提升”的更多信息,请参阅伟大的答案,谢谢!也谢谢你的文章@JonathanBrooks
bindFunctions(){
var room = io.sockets.adapter.rooms["myRoom"];
Object.keys(room).forEach(function(key) {
var socketId = room[key];
var socket = io.sockets.connected[socketId];
socket.on('my event',function(submit){
console.log(socket.myVariable);
});
});
}