Ответы пользователя по тегу Node.js
  • Почему MongoDB работает медленно?

    @Faliah
    В тэгах вижу mongoose. Пара советов по работе с ним: попробуйте поиграться с ограничением полей через find().select(/* объект с полями */). По умолчанию mongoose возвращает коллекцию своих обёрток над JS-объектами, которые довольно тяжелые. Получить POJO можно с помощью find().lean(). Чтобы не ждать, пока вам вернётся вся коллекция из 1500 записей, можно воспользоваться курсорами со стримами и работать с данными пачками.

    Но тут действительно сложно сказать в чём проблема - железо действительно не плохое, но проблема скорее всего в IO цикле, как это обычно и бывает, в зависимости от количества узлов между клиентом, сервером и сервером БД. Может у вас прокси перед сервером стоит и не тянет под нагрузкой, может сервер перегружен запросами и вы ждёте в очереди, может к БД много коннектов и вы, опять же, ждёте.
    Ответ написан
    1 комментарий
  • Как "обойти" асинхронность в данном примере?

    @Faliah
    Ваш первый res.send отправляет все заголовки и тело, что завершает вес процесс запрос-ответ и закрывает возможность использовать текущий объект res для отправки чего-либо. В данном случае вам нужно убрать из кода первый вызов res.send и вы получите "Hello 2". Никаих обходов асинхронности, глобальных переменных и прочего вам не нужно. Переменная res будет и так доступна внутри коллбэка, если вы не перекрываете её где-то в области видимости.
    Ответ написан
    Комментировать
  • Как причесать код?

    @Faliah
    Упростить можно всё, что угодно, просто взшлянув на проблему с другой стороны. Есть несколько вопросов по коду:
    3182804ed7444150bdab28a4ac0e5588.png

    1) В функцию redis.hmget вы передаёте две строки 'level' и code lang="javascript">'language' (в красных прямоугольниках). Нельзя ли избавиться от них, ведь, по сути это константы? То же самое касается их аналогов в красных прямоугольниках со скруглёнными уголками. Если в каждую функцию redis.hmset нужно обязательно передать 'level', то, на мой взгляд полезно было бы сделать обёртку
    function memoizeArguments() {
      
      const memoizeArgs = Array.from(arguments);
      
      return function(fun) {
        return function() {
          fun.apply(null, memoizeArgs.concat(Array.from(arguments).join()));
        }
      }
      
    }
    
    app.on('message', msg => {
      
      const telegramID = msg.from.id,
            encodedID = `id${telegramID}`,
            text = msg.text;
    
      // Сохраняем аргументы, чтобы упростить сигнатуры вызовов, создаём обертки с закэшированными аргументами
      const withId = memoizeArguments(telegramID);
      const appSendMessage = withId(app.sendMessage);
      
      const withEncodedIdAndLevel = memoizeArguments(encodedID, 'level');
      const redisHmSet = withIdAndLevel(redis.hmset);
      
      
    
      redis.hmget(encodedID, 'level', 'language', (err, res) => {
        
        let sendMessageArgs = null;
        let redisHmSetArgs = null;
        
        switch (res[0]) {
          case 'language':
            sendMessageArgs = message[text].languageGood;
            redisHmSetArgs = ['user_name', 'language', msg.text];
          break;
    
          case 'user_name':
            sendMessageArgs = [message[res[1]].nameGood, options];
            redisHmSetArgs = ['user_name', text, 'change_services']; // тут парамет 'level' передастся 2м аругментом, а не 4м
          break;
    
          case 'change_services':
            
            switch(text) {
                
              case 'some text':
                sendMessageArgs = message[res[1]].flpPhone;
                redisHmSetArgs = ['flp', 'sublevel', 'phone'];
                break;
    
              case 'another text':
                redisHmSetArgs = 'ooo';
                break;  
                
              case 'other':
                redisHmSetArgs = 'reg';
                break; 
                
              default:
                sendMessageArgs = message[res[1]].changeServicesBad;
                break;
            }
           
          break;
        }
    
        if (sendMessageArgs) appSendMessage(sendMessageArgs);
        if (redisHmSetArgs) redisHmSet(redisHmSetArgs);
        
      });
    });


    Вообще говоря логику фомирования массивов с аргументами тоже можно упростить и сделать единообразной, либо делать функции app.sendMessage и redis.hmset менее полиморфными - в разных вызовах передается разное число аргументов и иногда в разном порядке. Это сложно для понимания
    Ответ написан
    Комментировать
  • Почему promise.catch() не перехватывает ошибку?

    @Faliah
    Желательно указать каким драйвером, для какой БД вы пользуетесь. Мне странно видеть в коде на node.js блокирующий запрос к БД, когда почти для любых i/o операций используются неблокирующие вызовы с коллбэками. Вполне возможно, что вам нужно вручную выбросить исколючение в коллбэке/зареджектить промис при наличии err, в вызове коллбэка после запроса
    Ответ написан
    Комментировать