我正在尝试从数据库中获取文档(问题)并将它们存储在一个数组中以供进一步使用(问题将被提交给玩家)。
但是,当我调用findOne()并将其结果添加到数组时,回调后数组为空。即使它包含数据!
private Questions: iGeneralQuestion[];
private LoadQuestions(): iGeneralQuestion[] {
const result: iGeneralQuestion[] = [];
for (let qid of this.GeneralArguments.questionIds) {
QuestionModel.findOne({ id: qid }, (err: any, question: any) => {
if (err) return err;
if (!question) return question;
this.Questions.push({
questionId: question.id,
question: question.question,
answer: question.answer,
otherOptions: question.otherOptions,
timeLimit: question.timeLimit,
difficulty: question.difficulty
//explanation: question.explanation
//pictureId: question.pictureId
});
console.log(this.Questions); //The array is full here! (Gets filled with each iteration)
});
}
console.log(this.Questions); //But it doesn't contain anything here!
return result;
}
这是加载文档的代码,并将其内容保存在数组中。
我尝试使用promise函数和find()而不是findOne()..无济于事!
我完全迷失了,因为它不应该是某种范围错误。 Questions数组是一个字段变量,但它最终似乎已被清除。
感谢任何帮助!
答案 0 :(得分:0)
当您致电QuestionModel.findOne({ id: qid }, (err: any, question: any) => {...});
时,您正在注册一个回调函数,该函数将在找到文档后调用。但在此期间(当findOne(...)
查找文档时),其余代码继续执行。
因此,在您调用QuestionModel.findOne(...)
之后,for循环继续。你还没有找到一份文件 - 这是在后台发生的。最终,for循环将完成,页面上的最后一个console.log(this.Questions)
将被调用,然后是return result;
。但是,findOne(...)
仍然在后台查找文档。它还没有找到任何东西,所以console.log(this.Questions)
没有显示任何内容。此时阵列仍为空。稍后,在findOne(...)
最终找到文档后,调用回调。
在处理像这样的异步代码时,可能值得研究一下promises:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
答案 1 :(得分:0)
更多优化方式(减少数据库操作)而不是查找每条记录,一次性查找所有重新编码而不是创建结果。希望这会有所帮助:)
private LoadQuestions(cb){
const result: iGeneralQuestion[] = [];
QuestionModel.find({
id: {
$in: this.GeneralArguments.questionIds // Array of all ids
}}, (err: any, questions: any) => {
if (err) cb(err);
questions.forEach((question) => {
if (question) {
result.push({
questionId: question.id,
question: question.question,
answer: question.answer,
otherOptions: question.otherOptions,
timeLimit: question.timeLimit,
difficulty: question.difficulty
//explanation: question.explanation
//pictureId: question.pictureId
});
}
});
return cb(null,result);
});
}