Как мне использовать переменные внутри обратных вызовов более низкого уровня?

#javascript #node.js

#javascript #node.js

Вопрос:

Я впервые пытаюсь использовать WebSockets и создаю приложение со списком задач. Я использую Express и Socket.ввод-вывод и повторный запуск.

В следующем коде socket.emit(‘items’, {items: redisItems}) терпит неудачу, сообщая, что emit не может быть выполнен для undefined . Я знаю, что client.hgetall — это асинхронный вызов, и я должен каким-то образом заставить его выполнить after . Как мне это исправить? Использую ли я что-то вроде фьючерсов или это можно сделать с небольшим исправлением того, что у меня есть прямо сейчас?

 io.sockets.on('connection', function (socket) {
  socket.on('getItems', function (socket){
    var redisItems = new Array;
    callback = function(err,obj){
      for ( att in obj) {
        item = new Object();
        item.key = att;
        item.done = obj[att];
        redisItems.push(item);
        console.log(redisItems.length);
        console.log(item.key);
      }
      socket.emit('items', {items: redisItems})
    };
    client.hgetall("items", callback);
  });
});
  

Sidenote: то, что у меня сейчас есть, выглядит следующим образом: 1) браузер запрашивает страницу 2) Как только браузер получает страницу, он подключается через WebSocket и запрашивает элементы todo (таким образом, 2 запроса).
В будущем я бы предпочел что-то вроде 1) браузер запрашивает страницу 2) сервер выдает страницу и отправляет элементы, как только это будет сделано.

Ответ №1:

Вы перезаписываете свой объект сокета в getItems обратном вызове. В то время как начальное io.sockets событие подключения возвращает socket , последующие socket.on события не возвращают другой socket объект, они возвращают данные для события. Попробуйте что-то вроде:

 io.sockets.on('connection', function (socket) {
  socket.on('getItems', function (data){
    var redisItems = new Array;
    callback = function(err,obj){
      for ( att in obj) {
        item = new Object();
        item.key = att;
        item.done = obj[att];
        redisItems.push(item);
        console.log(redisItems.length);
        console.log(item.key);
      }
      socket.emit('items', {items: redisItems})
    };
    client.hgetall("items", callback);
  });
});