我的功能与重定向至路线之间存在延迟

时间:2019-01-28 13:34:12

标签: javascript node.js express routes

我正在nodeJs中的一个带有express的页面上工作,该页面返回了我一个表。尝试访问它时,我的页面上包含我的数据的变量“ allMusique”出现错误,但是重新加载一次后,页面正确显示了我的数据。请问有人看错了吗?

这是我的代码:

var express = require('express');
var router = express.Router();
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
var allMusique;
var idMaxMusique;

router.get('/', function(req, res, next) {
    function getAllMusique(){
        MongoClient.connect(url, function(err, db) {
            if (err) throw err;
            var dbo = db.db("projet_node");
            dbo.collection("musiques").find({}).toArray(function(err, result) {
                if (err) throw err;
                allMusique = result;
                var size = allMusique.length-1;
                idMaxMusique = parseInt(result[size].id)+1;
            });
        });
    }

    getAllMusique();
    res.render('musiques', { resultat: allMusique, idMax: idMaxMusique });
});

module.exports = router;

3 个答案:

答案 0 :(得分:3)

第一次调用res.render时,尚未设置变量allMusique,因为它没有等待数据库访问完成,因此在第二次尝试中由于第一次访问而已将其写入。

我建议在Mongoclient.connect内部调用res.render

router.get('/', function(req, res, next) {
    MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbo = db.db("projet_node");
        dbo.collection("musiques").find({}).toArray(function(err, result) {
            if (err) throw err;
            allMusique = result;
            var size = allMusique.length-1;
            idMaxMusique = parseInt(result[size].id)+1;
            res.render('musiques', { resultat: allMusique, idMax: idMaxMusique });
        });
    });
});

如果您真的想保留结构,可以将res.render放入函数回调中

function getAllMusique(callbackFunction){
    MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbo = db.db("projet_node");
        dbo.collection("musiques").find({}).toArray(function(err, result) {
            if (err) throw err;
            allMusique = result;
            var size = allMusique.length-1;
            idMaxMusique = parseInt(result[size].id)+1;
            callbackFunction();
        });
    });
}

getAllMusique(()=>res.render('musiques', { resultat: allMusique, idMax: idMaxMusique }));

或在值已被写入时使functon返回promise

function getAllMusique(){
    return new Promise((resolve, reject) => {
        MongoClient.connect(url, function(err, db) {
            if (err) throw err;
            var dbo = db.db("projet_node");
            dbo.collection("musiques").find({}).toArray(function(err, result) {
                if (err) throw err;
                allMusique = result;
                var size = allMusique.length-1;
                idMaxMusique = parseInt(result[size].id)+1;
                resolve();
            });
        });
    });
}

getAllMusique().then(()=>res.render('musiques', { resultat: allMusique, idMax: idMaxMusique }));

答案 1 :(得分:0)

getAllMusique是一个异步功能。您只需要将渲染移到回调中

答案 2 :(得分:0)

解决方案之一也是使用异步/等待。

router.get('/', async function(req, res, next) {

//...

await getAllMusique();
res.render('musiques', { resultat: allMusique, idMax: idMaxMusique });

}

请注意,.get()中的回调现在为async,这使您可以await进行函数操作。