简体   繁体   English

Node.js console.log()给出了不可预测的答案

[英]Node.js console.log() gives unpredictable answer

This is a function to search test questions and match the answer given by the user and stored in the database. 该功能可以搜索测试问题并匹配用户给出的答案并存储在数据库中。 Console.log() displays all 6 questions but in random order. Console.log()以随机顺序显示所有6个问题。 And the value of num is 6 for each iteration. 每次迭代的num值为6。 if I do console.log(num) without finding anything from the database then I correctly display values 1,2,3,4,5,6. 如果我在没有从数据库中找到任何内容的情况下执行console.log(num),那么我会正确显示值1,2,3,4,5,6。

function(req,res){
    var arr = [2,1,3,4,1,4],score=0, num=0;
    Test.find({name:req.params.testnum}).
    populate({
        path: 'question',
        model: 'Testques'
    }).
    exec(function(err,test){
        console.log(test)
        if(err){
            res.status(500).send('DB error');
        }
        else{
            arr.forEach(myFunction)
            function myFunction(value){
                num+=1;
                Testques.find({Serialnum:num},function(err,ques){
                    console.log(num);
                    if(err){
                        console.log(err);
                    }
                    else{
                        console.log(ques);
                        console.log(ques[0].answer);
                        if(ques[0].answer == value){
                            score=score+4;
                            console.log(score);
                        }
                    }
                })
            }
        }
    })
}

I agree with what CRice has to say about it. 我同意CRice对此有何评论 Inside the else of the callback, you're trying to run a synchronous forEach loop, but you're running an asynchronous block of code ( namely : Testques.find ) inside it, which would not work the way you wish it to work. 在回调的else中,您试图运行一个同步的forEach循环,但在其中运行了一个异步代码块(即: Testques.find ),这无法按您希望的方式工作。

An elegant solution could be, to promisify your Mongoose calls, ( using promisifying utils available ), and then, once promisified, either use Promise.all to resolve the arrays of these queued up promises of Testques.find that you may push inside it. 一个不错的解决方案是,使您的Mongoose调用(使用promisifying utils)繁多,然后一旦实现,要么使用Promise.all来解决这些排队的Testques.find的数组, Testques.find发现您可以将其压入其中。

Otherwise, you can also proceed as follows : Move your function inside the argument of the forEach to another method outside this method's scope, and then use basi knowledge of recursion to achieve what you wish to. 否则,您还可以按照以下步骤进行操作:将forEach参数内的函数移到该方法范围之外的另一个方法,然后使用递归的基础知识来实现​​您想要的目标。 It should resemble somewhat to this : 它应该与此类似:

function cbIterator($index, arr, num, score) {
    if ($index < arr.length) {
        const value = arr[$index];
        num++;
        Testques.find({ Serialnum: num }, function (err, ques) {
            console.log(num);
            if (err) {
                console.log(err);
            }
            else {
                console.log(ques);
                console.log(ques[0].answer);
                if (ques[0].answer === value) {
                    score = score + 4;
                    console.log(score);
                }
                cbIterator($index + 1, arr, num, score);
            }
        });
    }
    return;
}

function myTestFunction(req, res) {
    // A bit of ES6. Feel free to replace the const / let with var if you are not comfortable with those
    const arr = [2, 1, 3, 4, 1, 4];
    let score = 0, num = 0;
    Test.find({ name: req.params.testnum })
        .populate({
            path: 'question',
            model: 'Testques'
        }).exec(function (error, test) {
            if (error) {
                res.status(500).send('DB Error');
            } else {
                let $index = 0;
                cbIterator($index, arr, num, score);
            }
        });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM