В функции обратного вызова отсутствует область для требуемых данных - PullRequest
0 голосов
/ 27 апреля 2018

У меня проблема с тем, что переменная функции обратного вызова теряет свою область видимости

. У меня есть следующие 2 объекта в массиве (упрощенно, чтобы показать проблему)

const search = [{socket: new WebSocket('ws://live.trade/123')}, 
                {socket: new WebSocket('ws://live.trade/xyz')}];

Затем я выполняю forEach для них, пытаясь зарегистрировать URL сокетов, как только сокет открыт.

search.forEach(function(element){
    element.socket.on('open', function open() {
      console.log(element.socket.url);
    });
});
*actual output*
ws://live.trade/xyz
ws://live.trade/xyz

*expected*
ws://live.trade/123
ws://live.trade/xyz

Мне кажется, что причина в том, что когда функция open () запускает элемент, он находится вне области видимости и просто использует то, что там было в последний раз (будучи ws: //live.trade/xyz). Это правильно? И, наконец, каким будет способ исправить это? Реальное использование для этого - когда сокет открыт, мне нужно отправить данные версии на сервер через сокет, который вызвал его ... У меня будет много сокетов в реальности, и я не хочу писать "socket.on (" open «...)» для каждого отдельного.

Есть предложения?

Большое спасибо!

1 Ответ

0 голосов
/ 27 апреля 2018

Ваш обратный вызов (, т.е. в socket.on () ) использует переменную element из forEach(). Исходя из вашего фактического результата, это может означать, что:

1. Объем выпуска

Переменная может быть " переопределена " в течение итераций из-за механизма области видимости javascript / node, это не относится к предоставленному вами коду, но это распространенная проблема при работе с областями внутри циклов.

в этом случае вам нужно будет сделать:

search.forEach(function(element){
    element.socket.on('open', function(){
      console.log(this.socket.url);
    }.bind(element));
});

Пояснение:

  • bind() передает свой первый аргумент (в данном случае переменную element ) анонимной функции как this внутри нее.
  • Внутри вашей функции обратного вызова this.socket эквивалентно element.socket на соответствующей итерации

[ОБНОВЛЕНИЕ] после того, как указано Феликс Клинг , forEach () предоставляет область действия для каждого элемента.

См. bind для более подробной информации.

2. Проблема зависимости

Если это не проблема области действия, это может означать, что используемая вами библиотека не работает должным образом. Возможно, попробуйте войти в element внутри forEach (), чтобы проверить, соответствуют ли объекты WebSocket тому, что вы ожидаете.

редактировать

  • Для получения дополнительной информации о циклах node / js и справках: см. здесь
  • Для закрытия узла / js в целом: см. здесь
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...