承诺没有将所有数据都提取到前端

时间:2018-09-22 04:02:40

标签: javascript node.js angular mongodb

我正在使用promise来获取一些基于数据的级别,对于更高级别(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 :(得分:0)

此循环中至少存在一个错误。承诺是异步的,循环是同步的。因此,在大多数情况下,您将要遍历这些内容。许诺函数将在可能的时候被推送到队列中运行,到它们运行时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。

答案 1 :(得分:0)

您也可以尝试使用数组映射功能使其更简单

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) => {
    });
})

}