首页 > 解决方案 > NodeJS / Express 为什么我得到“无法读取未定义的属性'then'”?

问题描述

我提前道歉,因为我看到了关于这个主题的其他问题,但我不明白我做错了什么以及如何解决它。请看一下我的代码:

function getSum(productID) {
  Rating.aggregate(
    [
      {
        $group: {
          _id: "$productID",
          total: {
            $sum: "$rating"
          }
        }
      }
    ],
    function (err, result) {
      if (err) {
        res.send(err);
      } else {
        //console.log("product-sum: " + req.body.productID)
        const count = result.find(item => item._id === productID.productID);
        console.log("getSum count: ", count.total);
        return count.total;
      }
    }
  );
}

router.route('/compute-rating').post((req, res) => {
  console.log("compute Rating: ", req.body.data);
  var productID = req.body.data;
  var sum = getSum(productID).then( //getting the error here

    res.json({ sum })
  );
});

getSum() 从 count.total 返回一个有效数字。

得到总和后,我计划将另一个 .then 链接到现有 then 并使用 productID 调用另一个函数,但我需要稍后在计算机评分路线中使用总和。

在代码中,我有一条注释显示错误“无法读取未定义的属性'then'”发生的位置。为什么我会收到此错误,我该如何解决?

谢谢。

编辑:我想展示我的最终解决方案,以便其他人可以从我的经验中受益。希望我没有在我的代码中创建任何重大的 Javascript 违规行为。我最终使用了 Promise.all,因为我必须基于 2 个返回值执行计算。

function getSum(productID) {
  return new Promise(async (resolve, reject) => {
    const result = await Rating.aggregate( //sum of a column in MongoDB
      [
        {
          $group: {
            _id: "$productID",
            total: {
              $sum: "$rating"
            }
          }
        }
      ]
    );
    
    try {
      var sum = result.find(item => item._id === productID.productID);

      if (sum !== undefined) {
        resolve(sum);
        console.log("getSum sum: ", sum);
      }
      else {
        reject("invalid product id");
      }

    }
    catch (e) {
      reject(e);
    }
  });
}

function getCount(productID) {
  return new Promise(async (resolve, reject) => {
    
    var result = await Rating.countDocuments(productID)
      .then(count => {
        console.log("getCount count:", result);
        var documentCount = { count: count }
        resolve(documentCount);
      })
      .catch(err => reject(err));
  });
}

router.route('/compute-rating').post((req, res) => {
  console.log("compute Rating: ", req.body.data);
  var productID = req.body.data;

  Promise.all([getSum(productID), getCount(productID)])
    .then(results => {
      console.log("compute rating results: ", results);

      if (results[1].count > 0) {

        res.status(200).json({ rating: results[0].total / results[1].count });
      }
      else {
        res.status(200).json({ rating: 0 });
      }
    })
    .catch(err => {
      res.status(400).json({ error: err });
    })

});

标签: node.jsexpresspromise

解决方案


then仅适用于返回 a 的函数promise。你的函数getSum没有返回任何东西,如果Rating.aggregate函数返回一个承诺,也就是接受 a then,那么你应该返回这个聚合,只需return在调用它之前添加。

现在 ifaggregate没有返回一个 Promise,我猜是因为你正在向它传递一个回调函数,你可能想要返回一个promise.resolve在这个回调主体中解析 using 的 Promise。


推荐阅读