socket.io Использование цикла for для добавления методов socket.on

Предполагать

socketMethods:{ update:function(data){ this.emit("test", data); console.log("socket.update"); }, test:function(data){ this.emit("test", data); console.log("socket.test"); } } 

Это ниже, и позволяет мне испускать «тест» и «обновление», и будут называться «тест» и «обновление»

 socket.on("test", function(data){ dummy.socketMethods.test.call(socket, data); }); socket.on("update", function(data){ dummy.socketMethods.update.call(socket, data); }); 

Эти ниже НЕ возможны … Каждый из них вместо этого будет называть «тест», если я испущу «тест» ИЛИ «обновление». Если я использую цикл FOR, все методы станут последним вызванным методом.

То есть: Если я переключил обновление и тест, чтобы сначала был тест, а обновление – вторым в объекте socketMethods. «update» всегда будет вызываться, независимо от того, спросил ли я «тест» или «обновление»,

 for(key in dummy.socketMethods){ socket.on(key, function(data){ dummy.socketMethods[key].call(socket, data); }); } var methods = ["test", "update"]; while(methods.length !== 0){ var method = methods.pop(); console.log(method); socket.on(method, function(data){ dummy.socketMethods[method].call(socket, data); }); } var methods = ["test", "update"]; for(var i = 0; i < methods.length; i++){ console.log(i); socket.on(methods[i], function(data){ console.log(i); dummy.socketMethods[methods[i]].call(socket, data); }); } 

CLUE: цикл for, использующий ‘i’, имеет два console.logs. Второй console.log возвращает «2»

Почему это происходит? И как я могу использовать цикл for для подключения моих методов socketMethods?

Вы делаете общую ошибку, полагая, что закрытие «ловушки» значения переменной внешней функции в момент ее создания . Это не так. Он «ловушки» ссылается на переменную внешней функции, и ее значение будет тем, что внешняя переменная имеет во время закрытия. Если вы создаете замыкания в цикле, это значение будет тем, что было в конце цикла.

Способ обойти это – создать закрывающее закрытие, которое использует значение внешней переменной в качестве аргумента. Один из способов сделать это – создать вспомогательную функцию, которая генерирует ваше закрытие. В первом примере вы могли бы сделать

 function makeOn(key) { return function(data) { dummy.socketMethods[key].call(socket, data); } } for(key in dummy.socketMethods){ socket.on(key, makeOn(key)); } 

Теперь в каждом закрытии key будет новой созданной переменной (отличающейся между замыканиями), установленной на соответствующее значение.

Также можно использовать немедленный вызов функции (что некоторые называют «функцией самоисполнения»), чтобы сделать то же самое немного более лаконично, но также несколько менее читаемо.