javascript - 异步 mongoDB find() 方法的问题
问题描述
我正在尝试从 mongoDB 获取一些数据并将其存储在一个数组中,然后将该数组传递给 ejs 文件。问题似乎是mongo在查询结果时,db代码执行后的代码,给ejs发送了一个空数组。结果是在执行渲染函数之后出现的,因此没有数据发送到 ejs..
app.get('/', (req, res) => {
var batData = [];
//console.log("get req");
MongoClient.connect(url, (err,db)=>{
if(err) throw err;
console.log("Enter DB");
var dbo = db.db("MatchDB");
batData = dbo.collection("Batting").find().toArray((err,res)=>{
console.log("Query Success");
});
console.log("Exit DB");
db.close();
})
// batData remains empty when these lines of code executes.
res.render('index', {
batting: batData
});
});
输出顺序如下: Enter DB Exit DB Query Success
预期顺序:进入数据库查询成功退出数据库
解决方案
在这里使用承诺
//change your query to function
functon query(){
//now here return a promise
return new Promise((resolve, reject) => {
MongoClient.connect(url, (err,db)=>{
if(err) reject(err) // reject the err
var dbo = db.db("MatchDB");
dbo.collection("Batting").find( (err, data) => {
console.log("Query Success");
batData = data//save your data here or do anything
db.close(); //close the db
resolve(batData) //this will get returned to the caller
});//dbo find ends
}) //mongo client ends
})//promise end
}//function ends
//now in your app.get route
// see here i marked this async, for using await
app.get('/', async (req, res) => {
let batData = await query() // this will wait until it gets resove or rejected
res.render('index', {
batting: batData // now you will have data here
});
});
这里有几点可以帮助你
- 承诺被解决或拒绝
- Promise 的调用者函数将等待它从 Promise 函数返回结果,如果您不想等待 Promise 完成,您可以再次处理此问题
- 异步等待只是以更简洁的方式处理承诺的方法,从代码中删除回调地狱
- 每当您需要使用 await 时,您必须标记其异步所在的函数,正如您在 app.get 回调函数中所做的那样
- 现在 await 将阻塞代码,直到它完成、拒绝或解决
- 之后它将转到代码的 res.render 部分
推荐阅读
- cmake - 有没有办法全局设置 cmake 属性?
- ip - 逐页阅读并被页面阻止
- java - 如何从android应用程序中的txt文件中获取部分行
- r - 匹配字符串末尾的 1-2 位数字,同时用数字查找预定义字符串
- windows - windows用户之间如何分开以太网连接?
- spring-boot - maven 的 gradle 类似物是什么
测试 ? - javascript - 来自 Json 的过滤器数组
- java - 如何使用 Try Catch Block 捕获特定的自定义异常
- python - 从文件名以“df”开头的目录中删除所有文件
- c# - 捕获的变量 IndexOutOfBounds