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

У меня проблема с манипулированием глобальным массивом.

Код работает хорошо, если он написан так

  function getChatBox(originMessage) {
    return new Promise((resolve, reject) => {
      resolve(
        Message.aggregate([
          {
            $match: { _id: originMessage }
          },
          {
            $unwind: "$subMessages"
          },
          {
            $lookup: {
              from: "messages",
              localField: "subMessages",
              foreignField: "_id",
              as: "chained"
            }
          },
          {
            $unwind: "$chained"
          },
          {
            $project: { chained: 1, _id: 0 }
          }
        ])
      );
    });
  }

  let chatBoxes = [];
  if (user.messages.length > 0) {
    user.messages.forEach(async msg => {
      //let chatBox = await getChatBox(msg.originMessage);
      //chatBoxes.push(chatBox);
      //chatBoxes.push(await getChatBox(msg.originMessage));
      chatBoxes.push("cool");
      console.info(chatBoxes);
    });
  }
  console.info("outer", chatBoxes);

И результат такой, когда он работает

Однако как только я добавляю строку кода (для извлечения данных из базы данных), доза глобального массива не меняется.

между ** ** - добавленная строка кода (let chatBox = await getChatBox (msg.originMessage);):

      function getChatBox(originMessage) {
        return new Promise((resolve, reject) => {
          resolve(
            Message.aggregate([
              {
                $match: { _id: originMessage }
              },
              {
                $unwind: "$subMessages"
              },
              {
                $lookup: {
                  from: "messages",
                  localField: "subMessages",
                  foreignField: "_id",
                  as: "chained"
                }
              },
              {
                $unwind: "$chained"
              },
              {
                $project: { chained: 1, _id: 0 }
              }
            ])
          );
        });
      }

      let chatBoxes = [];
      if (user.messages.length > 0) {
       user.messages.forEach(async msg => {
          **let chatBox = await getChatBox(msg.originMessage);**
          //chatBoxes.push(chatBox);
          //chatBoxes.push(await getChatBox(msg.originMessage));
          chatBoxes.push("cool");
          console.info(chatBoxes);
        });
      }
      console.info("outer", chatBoxes);

И вывод показывает это: Я не знаю, почему порядок смены логов

Пожалуйста, помогите мне понять, что происходит. Я хочу вставить в глобальный массив (chatBoxes) полученные данные, но за пределами функции массив все еще пуст (не пуст, если я добавлю в функцию простую строку).

Я подозреваю, что код после forEach запускается до того, как завершит цикл. Может в этом проблема?

Спасибо !

Если вы можете, отредактируйте ваш фактический код как текст в своем вопросе - изображения кода в одиночестве - это утомительно и сложно для работы и отладки. Это заставляет тех, кто иначе хотел бы помочь вам, сначала сделать расшифруйте ваше изображение, что является пустой тратой времени.

CertainPerformance 27.10.2018 11:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
243
2

Ответы 2

Ваша переменная chatBox объявляется с помощью оператора let, тогда chekBox будет доступен только в его области (анонимная функция внутри user.message.forEach().

Измените let с помощью оператора var, и если checkBox является глобальной переменной, было бы лучше объявить его вне области действия forEach(), возможно, в верхней части function getChatBox()

Спасибо, но это не сработало. Поменял на var. chatBoxes уже находится за пределами forEach. Когда выборка происходит каким-то образом, глобальная переменная изменяется только внутри forEach, а затем за ее пределами значение массива такое же, как оно было инициировано. Также он изменяет порядок журналов, он пропускает код внутри forEach, а затем запускает его.

עדי קוש 27.10.2018 12:48

Это потому, что вы повторно объявляете checkBox с помощью «let checkBox» внутри forEach (), это вопрос указателя (невидимого для программиста с javascript). Я думаю, будет работать, если вы отключите оператор let внутри forEach ()

Aldo Maria Landini 27.10.2018 12:53

Я изменил его, но он не работает :( Переменная chatBox - это единственный элемент, который я хочу поместить в массив chatBoxes.

עדי קוש 27.10.2018 13:19

Можете ли вы поделиться данными, представленными originMessage, чтобы четко подтвердить свой код? Иначе я не смогу тебе помочь.

Aldo Maria Landini 27.10.2018 15:28

Конечно, originMessage - это идентификатор документов сообщений в mongoDB (например: ObjectId ("5bd33cce32b3e62d1450aa12")). Сообщения источника - это первые отправленные сообщения. каждое ответное сообщение на исходное сообщение имеет идентификатор originMessage в своем документе.

עדי קוש 27.10.2018 18:07

Я создал своего рода ваш пользовательский объект, но код работает, только если я уберу ключевое слово "await" перед getChatBox (msg.originMessage). Это странно. Кстати без await "chatBox (результат getChatBox ()) является объектом обещаний, но пустым {} ... У вас такая же ошибка?

Aldo Maria Landini 27.10.2018 20:37

Что такое Message.aggregate ()? Может быть, будет лучше, если вы дадите мне хотя бы одно из значений, возвращаемых Message.aggregate (), потому что целью этого потока является не Message.aggregate. В любом случае мы близки

Aldo Maria Landini 27.10.2018 20:40

Я починил это. Я пока не знаю, как это сделать. Я использую обычный цикл for вместо forEach. appernatly использование async / await внутри forEach не работает. Я узнаю об этом. Подробнее читайте здесь: https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404

Другие вопросы по теме