node.js - 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 });
})
});
解决方案
then
仅适用于返回 a 的函数promise
。你的函数getSum
没有返回任何东西,如果Rating.aggregate
函数返回一个承诺,也就是接受 a then
,那么你应该返回这个聚合,只需return
在调用它之前添加。
现在 ifaggregate
没有返回一个 Promise,我猜是因为你正在向它传递一个回调函数,你可能想要返回一个promise.resolve
在这个回调主体中解析 using 的 Promise。
推荐阅读
- asp.net-mvc - SignalR 使用 Azure 服务总线主题向外扩展
- javascript - 如何循环 td_i.innerHTML = message;
- ios - GMSAutocompleteResultsViewController 显示有限的结果?
- php - FFMPEG 在转换视频时使我的网站关闭
- java - 带有进度条的 Android 音乐播放器通知
- java - 初始 springboot 启动项目设置 - 面临问题
- ruby-on-rails - omniauth-google 注销不起作用
- python - Pandas DF:将作为字符串转换为新列的数字行求和
- python - 在 Python 中将矩阵列表转换为仅一个 2D 矩阵
- xcode - Xcode 9隐藏故事板状态栏