2013-05-02 2 views
2

У меня есть сервер socket.io, который генерирует много событий, и я хочу поймать их все и напечатать аналогичное сообщение. Прямо сейчас, я делаю это:обработчик события, который знает имя события

for (var event in {eventA: 1, eventB: 1, eventC: 1}) { 
    this.translationSocket.on(event, function(result) { 
     console.log("Server sent an event of type "+event); 
    }); 
} 

Когда сервер отправляет EVENTA, событие В и eventC, я вижу это:

Server sent an event of type eventC 
Server sent an event of type eventC 
Server sent an event of type eventC 

т.е. моя программа перехватывает все события, но всегда отображает тип eventC. ..

Я попытался следующими вариантами:

  • удалить «вар» перед «событием» внутри «за»: «для (события ...»
  • добавление оператора «var msg =» Сервер отправил событие типа «+ event;» либо перед оператором «on», либо непосредственно перед оператором «console.log», а затем «console.log (msg)» , не

Ни один из этих вариантов работали ...

Что я должен делать?

ответ

1

Это не имеет никакого отношения к socket.io или node.js, это хорошо известный JavaScript «quirk». Значение event оценивается, когда код выполняется, когда цикл завершен. Чтобы сохранить значение, вам нужно обернуть элемент в вызов функции.

var listen = function(socket, event) { 
    socket.on(event, function(result) { 
     console.log("Server sent an event of type "+event); 
    }); 
} 


for (var event in {eventA: 1, eventB: 1, eventC: 1}) { 
    listen(event); 
} 

Или (короткая версия):

for (var event in {eventA: 1, eventB: 1, eventC: 1}) { 
    (function(event) { 
     this.translationSocket.on(event, function(result) { 
      console.log("Server sent an event of type "+event); 
     }); 
    })(event); 
} 
1

В for (var event in ...) вы объявляя переменную и из-за переменных правил области видимости в JavaScript он будет действовать вне цикла Еогеасп.

Переменная event становится eventC в конце цикла. Значит, это значение, когда вы хотите распечатать, будет eventC.

Вы можете сделать что-то вроде этого:

function generateCallback(e, result) { 
    return function() { 
     console.log("Server sent an event of type " + e); 
    }; 
} 

var e; 
// ... 
for (e in {eventA: 1, eventB: 1, eventC: 1}) { 
    this.translationSocket.on(e, generateCallback(e, result)); 
} 

Чтобы избежать путаницы you'd better not to declare variables in for statements.

А также это лучше, not to make functions within a loop. Вот почему я использовал generateCallback вместо функции обратного вызова в цикле.

+0

Спасибо, эта проблема «вар» действительно запутанна. –

0

Я бы использовал socket.io-events на npm. Вы можете захватить все события и обрабатывать их, но вы не хотите связывать отдельные обработчики.

var io = require('socket.io')(3000); 
var router = require('socket.io-events')(); 
router.on('*', function (sock, args, next) { 
var name = args.shift(), msg = args.shift(); 
sock.emit('received event', name, msg); 
}); 
io.use(router);