Обещания не получают все данные для веб-интерфейса - PullRequest
0 голосов
/ 22 сентября 2018

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

module.exports.getQ = function(req, res) {
  var promises = [];
  var data = [];
  User.aggregate([
    {
      $match: {
        reportingManager: req.user.user.empId
      }
    }
  ], function(err, data) {
    if (err)
      console.log(err);
    else {
      for (var i = 0; i < data.length; i++) {
        promises.push(new Promise((resolve, reject) => {
          Quotation.find({
            $or: [{
              salesCrm: data[i].empId
            }, {
              salesCrm: req.user.user.empId
            }]
          }, function(err, result) {
            if (err) {
              console.log(err);
              reject(err);
            } else {
              console.log(JSON.stringify(result));
              resolve(result);
            }
          }).sort({
            createdOn: 1
          })
        }))
        Promise.all(promises).then((allInsts) => {
          res.json(allInsts[0]);
        }).catch((error) => {
        });
      }
      console.log(JSON.stringify(data) + "----------------");
    }
  })
}

Проблема, с которой я сталкиваюсь, заключается в том, что в бэкэнде он получает все данные правильно, но не во внешнем интерфейсе.Когда я обновляю страницу, на ней иногда отображаются некоторые пользовательские данные.

enter image description here

Только данные L2 и любая из данных L3 извлекаются ввнешний интерфейс, но не все данные L3 вместе с L2.

Кто-нибудь может помочь мне решить эту проблему?

Данные, которые отсутствуют:

[{
  "sourceLanguage": "English",
  "targetLanguage": "Telugu",
  "fuzzySlab": "New Words",
  "_id": "5b87c09660b9eb3f309f86b6",
  "fileName": "Episode 11",
  "serviceType": "Proof Reading",
  "rate": 1.25,
  "uom": "English Word",
  "quantity": 1000,
  "fileStatus": "Init"
}],
"salesCrm": "VVVV4500", 
"createdName": "Rakshith R", 
"tax": "Yes"

В интерфейсе: Не отображаются все данные пользователя.

enter image description here

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

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

module.exports.getQ = function(req, res) {
  var promises = [];
  var data = [];

  User.aggregate([
    {
      $match: {
        reportingManager: req.user.user.empId
      }
    }
  ], function(err, data) {
    if (err) {
        return console.log(err);
    }

    return Promise.all(data.map((item) => {
        Quotation
            .find({
                $or: [{
                    salesCrm: item.empId
                }, {
                    salesCrm: req.user.user.empId
                }]
            }, function(err, result) {
                if (err) {
                    return reject(err);
                }

                return resolve(result);
            })
            .sort({
                createdOn: 1
            })
    }))
    .then((allInsts) => {
      res.json(allInsts[0]);
    })
    .catch((error) => {
    });
})

}

0 голосов
/ 22 сентября 2018

В этом цикле есть как минимум одна ошибка.Обещания асинхронные, циклы синхронные.Так что в большинстве случаев здесь происходит то, что вы будете проходить через все это.Функции обещаний будут помещены в очередь для запуска, когда они могут, и к тому времени, когда они запустятся, i не будет значением, которое было при запуске итерации.

for (var i = 0; i < data.length; i++) {
    promises.push(new Promise((resolve, reject) => {
      Quotation.find({
        $or: [{
          // this will be the value of i when it executes Asynchronously
          salesCrm: data[i].empId
        }, {
          salesCrm: req.user.user.empId
        }]
      },
      //... Other stuff
    }))

Есть несколько способов обойти это, вы можете использовать let в своей петле и использовать babel или какой-либо другой транспортер.

for (let i = 0; i < data.length; i++) {

Или вы можете сделать это в старом стиле и создать немедленно вызванную функцию, которая будет сохранять значение при нажатии.Это выглядело бы примерно так

for (var i = 0; i < data.length; i++) {
    function(i){(promises.push(new Promise((resolve, reject) => {
      Quotation.find({
        $or: [{
          // this will be the value of i when it executes Asynchronously
          salesCrm: data[i].empId
        }, {
          salesCrm: req.user.user.empId
        }]
      },
      //... Other stuff
    }))}(i)

Обратите внимание, что мы создаем функцию, так что i находится в замыкании, и передаем ей текущий i, чтобы она сохранялась для дальнейшего использования.

Я рекомендую способ 1, если это возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...