node.js - Nodejs等待查询
问题描述
我将 Nodejs 与 MongoDB 一起使用(mongoose 和 express)。
由于我不信任用户数据,因此我需要从数据库中对其进行验证。
输入数据:
{
"id": "someid",
"nottrusteddata": [ {"id": "1"}, {"id" :"2"}]
}
在我的函数中,我正在验证数据:
router.post("/validate", (req, res,next) =>{
let validated_data = validate_data(req);
console.log(JSON.stringify(validated_data));
const mydata = new Mydata({
id: req.body.id,
lst : validated_data
});
console.log("mydata: " + JSON.stringify(mydata));
/* Some Usefull stuff is here */
res.status(200).json();
}
function validate_data(req){
let validated_data = []
for(let i = 0; i < req.body.nottrusteddata.length; i++)
{
Databaseobject.findOne({'id': req.body.nottrusteddata[i].id})
.exec()
.then(dbobject =>{
if(dbobject) // not undefined, it exists in the database
{
// Some logic with the object returned from the database
let tmp_object = {};
tmpobject.id = dbobject.id;
// Append it to the list, so that the upper function can use it
validated_data.push(tmp_object);
}
})
}
return validated_data;
}
所需的输出应该包含来自数据库的正确信息,但是,由于 nodejs 的异步性质,validated_data
返回 null。
我也尝试过使用Promise
. 我没能成功。
const validate_data = function(req){
return new Promise(function(resolve,reject){
let validated_data = []
for(let i = 0; i < req.body.nottrusteddata.length; i++)
{
Databaseobject.findOne({'id': req.body.nottrusteddata[i].id})
.exec()
.then(dbobject =>{
if(dbobject) // not undefined, it exists in the database
{
let tmp_object = {};
tmpobject.id = dbobject.id;
validated_data.push(tmp_object);
}
})
}
resolve(validated_data);
}
}
我究竟做错了什么?如何等待数据库查询完成,然后执行主要部分?如果只有一个验证,我可以使用.then()
. 但是,该列表可能包含许多元素,我需要等待所有元素都得到验证。
解决方案
您的Databaseobject.findOne()
调用是异步的,因此您的承诺将在其中任何一个完成之前解决。
您可以使用Promise.all
等待,直到您的所有承诺解决。
希望这对您有用:
router.post("/validate", (req, res) => {
validate_data(req.body.nottrusteddata)
.then(validated_data => {
const mydata = new Mydata({
id: req.body.id,
lst: validated_data
})
// Some useful stuff is here
res.status(200).json()
})
.catch(err => {
// Handle error
})
}
function validate_data(nottrusteddata) {
// Create array of pending promises
const promises = nottrusteddata
.map(item => {
return Databaseobject
.findOne({ 'id': item.id })
.exec()
})
// Wait for all promises to resolve
return Promise.all(promises)
.then(docs => {
return docs
.filter(dbobject => dbobject) // Filter out undefined
.map(dbobject => {
return { id: dbobject.id }
})
})
}
如果你愿意,你也可以在这里使用async-await:
router.post("/validate", async (req, res) => {
try {
const validated_data = await validate_data(req.body.nottrusteddata)
const mydata = new Mydata({
id: req.body.id,
lst: validated_data
})
// Some useful stuff is here
res.status(200).json()
}
catch(err) {
// Handle error
}
})
推荐阅读
- c - 每 N 个字符刷新一次输出缓冲区
- java - 最终和初始总和之间的最大差异
- vba - 如何在chrome中打开href链接到VBA?
- python - Python 3.9 – 使用 pandas 读取 google sheet 文件会导致回溯错误
- google-docs-api - 从 POST 导出链接到 https://www.googleapis.com/drive/v2/files/[ID]/copy 停止工作
- mongodb - Mongo 完整集合扫描是否会读取集合中的每个单词?
- oracle - 在 PL/SQL 中捕获 SQL/开发人员脚本输出
- python - python3 -m venv .venv 错误:[WinError 2]
- python - Pandas - df.compare() 如何更改自我/其他标签?
- javascript - 为什么我可以使用 document.getElementsByClassName() 删除某些元素,但不能删除其他元素?