Javascript 异步mongoDB find()方法存在问题
我试图从mongoDB获取一些数据并将其存储在一个数组中,然后将该数组传递到ejs文件中。问题似乎是,当mongo查询结果时,db代码执行后的代码将被删除,并向ejs发送一个空数组。结果在执行渲染函数之后出现,因此不会向ejs发送任何数据Javascript 异步mongoDB find()方法存在问题,javascript,node.js,mongodb,express,ejs,Javascript,Node.js,Mongodb,Express,Ejs,我试图从mongoDB获取一些数据并将其存储在一个数组中,然后将该数组传递到ejs文件中。问题似乎是,当mongo查询结果时,db代码执行后的代码将被删除,并向ejs发送一个空数组。结果在执行渲染函数之后出现,因此不会向ejs发送任何数据 app.get('/', (req, res) => { var batData = []; //console.log("get req"); MongoClient.connect(url, (err,db)=>{
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
});
});
输出的顺序如下:
输入DB
出口数据库
查询成功
预期订单:
输入DB
查询成功
Exit DBbatData被声明为数组,但随后在代码中将其设置为与find查询相等。您应该将其改为.push(),或者将其保存到一个新变量中,然后将其保存到.push()中
另外,在batData上使用const(而不是var)会抛出一个错误,从而显示这个错误。除非您使用var来支持较旧的代码,否则请改用const和let。batData被声明为数组,但稍后在代码中您将其设置为等于find查询。您应该将其改为.push(),或者将其保存到一个新变量中,然后将其保存到.push()中
另外,在batData上使用const(而不是var)会抛出一个错误,从而显示这个错误。除非您使用var来支持较旧的代码,否则请使用const和let。在此处使用promise
//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完成,您也可以处理这个问题
- AsyncWait只是以一种更简洁的方式处理promise的一种方法,可以从代码中删除回调hell
- 无论何时需要使用wait,都必须将其函数标记为异步,正如我在app.get回调函数中所做的那样
- 现在等待将阻止代码,直到完成、拒绝或解决为止
- 然后,它将转到代码的res.render部分
- 在这里使用承诺
//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完成,您也可以处理这个问题
- AsyncWait只是以一种更简洁的方式处理promise的一种方法,可以从代码中删除回调hell
- 无论何时需要使用wait,都必须将其函数标记为异步,正如我在app.get回调函数中所做的那样
- 现在等待将阻止代码,直到完成、拒绝或解决为止
- 然后,它将转到代码的res.render部分