【问题标题】:The array gets cleared after mongoose.findOne()mongoose.findOne() 后数组被清除
【发布时间】:2018-07-17 02:31:33
【问题描述】:

我正在尝试从数据库中取出文档(问题)并将它们存储在一个数组中以供进一步使用(问题将被询问给玩家)。

但是,当我调用 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 数组是一个字段变量,但它似乎最终被清除了。

感谢任何帮助!

【问题讨论】:

    标签: arrays node.js mongodb typescript mongoose


    【解决方案1】:

    当您调用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(...) 终于找到了一个文档,然后调用回调。

    在处理这样的异步代码时,可能值得研究一下 Promise:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

    【讨论】:

    • 呃。我不知道我是怎么错过的!非常感谢您的帮助。我通过在类构造函数中调用 find() 来修复它,而不是将其作为参数传递给它,并使用 questionsLoaded bool 进行最终检查。
    【解决方案2】:

    更多优化方式(减少数据库操作)而不是查找每条记录,一次找到所有重新编码而不是创建结果。希望这会有所帮助:)

    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);
        });
    } 
    

    【讨论】:

    • 谢谢!是的,我当时使用了 find(),但我在构造函数本身中调用了它,而不是将它作为参数传递!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 2021-05-08
    • 2017-09-21
    • 2021-01-13
    • 1970-01-01
    相关资源
    最近更新 更多