Проблема с методом async mongoDB find () - PullRequest
1 голос
/ 22 июня 2019

Я пытаюсь получить некоторые данные из mongoDB и сохранить их в массиве, а затем передать этот массив в файл ejs. Кажется, проблема в том, что пока mongo запрашивает результаты, код после кода db выполняется и пустой массив отправляется в ejs. Результаты приходят после выполнения функции рендеринга, и, следовательно, данные не отправляются в ejs ..

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


 });

Вывод в следующем порядке: Введите БД Выход из БД Запрос успеха

Ожидаемый заказ: Введите БД Успех запроса Выход из БД

Ответы [ 2 ]

0 голосов
/ 22 июня 2019

Используйте обещание здесь

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


});

Некоторые пункты здесь за вашу помощь

  • Обещание будет выполнено или отклонено
  • функция вызывающей стороны для обещания будет ждать, пока не получит результат от функции обещания, опять же, вы можете справиться с этим, если не хотите ждать, пока обещание будет завершено
  • async await - это просто способ обработать обещание более аккуратным путем удаления аддов обратного вызова из кода
  • всякий раз, когда вам нужно использовать await, вы должны пометить его функцию, в которой он лежит как асинхронный, как вы можете видеть в функции обратного вызова app.get
  • теперь ожидайте, будет блокировать код, пока он не будет завершен, отклонен или решен
  • после этого он перейдет к части кода res.render
0 голосов
/ 22 июня 2019

batData объявляется как массив, но затем в вашем коде вы устанавливаете его равным запросу поиска.Вы должны вместо этого использовать .push () или сохранить его в новой переменной, а затем .push () после этого.

Кроме того, использование const (вместо var) в batData привело бы к ошибке вместо этого, таким образом, показывая этоошибка.Если вы не используете var для поддержки старого кода, используйте вместо этого const и let.

...