我正在尝试创建类似Jeopardy的游戏。我在数据库中有游戏的主题。打开页面时,我希望它从数据库中随机获取6个主题。我将它们放在一个数组中,然后将其传递给我的ejs文件。问题是,当我将数组传递给ejs文件时,它始终为空。我了解这是由于猫鼬的承诺(实际上是查询)。我的问题是我不知道该如何处理。我已经阅读了Mongoose的文档,并在所有地方进行了搜索,但我无法弄清楚。
我已经尝试过使用回调,但是它们通常只会使程序挂起并且什么也不做。我曾尝试使用.then,但我一定使用错了,因为它无法满足我的要求。
app.get("/", function(request, response){
//My array to put the topics into
var questionArr = [];
//I need to know the number of items in db for random
var getQuestions = Questions.countDocuments({}, function(err, count){
for(var i = 0; i < 6; i++){
!function(i){
var rand = math.randomInt(count);
//Here I get a random topic and add to array
//Seems to work and actually get it
Questions.findOne().skip(rand).exec(function(err, result){
questionArr.push(result);
});
}(i);
}
});
//I thought this would make it wait for the function to finish so
//that I could have my full array, but apparently not
getQuestions.then(() => {
//this runs before the other functions and give me a length of 0
console.log(questionArr.length);
response.render("jeopardy.ejs", {questions: questionArr});
});
});
我只需要在从数据库中获取信息后运行渲染即可。但是,它仍然只在一个空数组下运行。感谢您的帮助,我是异步的新手。
答案 0 :(得分:1)
我发现您的代码有几个问题:
1)您正在混合promise和回调,这使事情变得更加复杂。该代码不起作用主要是因为您不等待Questions.findOne()结果。
2)没有Math.randomInt
要使其正常运行,必须与下面类似:
Questions.countDocuments()
.then((count) => {
return Promise.all([...new Array(6)].map(() => {
const rand = Math.floor(Math.random() * Math.floor(count));
return Questions.findOne().skip(rand).exec();
}))
})
.then((questionArr) => {
response.render("jeopardy.ejs", {questions: questionArr});
});
最好是使用async / await,这将使其更具可读性
app.get("/", async function(request, response){
const count = await Questions.countDocuments();
const questionArr = await Promise.all([...new Array(6)].map(() => {
const rand = Math.floor(Math.random() * Math.floor(count));
return Questions.findOne().skip(rand).exec();
}));
response.render("jeopardy.ejs", {questions: questionArr});
});
还请记住,最好进行适当的错误处理,但这是另一篇文章的主题:)