res.render仅在多个数据查询完成后

时间:2016-12-14 12:01:42

标签: javascript node.js mongodb express

在我的server.js中的app.get上,我从mongo db返回一个数据集,然后在将数据传递给它时渲染我的页面。

如下图所示:

//page load
app.get('/', (req, res) => {

    //find all data in test table
    var articles;
    db.collection('test').find().toArray((err, result) => {
        if (err) return console.log(err)
        articles = result

            // renders index.ejs and passes result to quotes
        res.render('./pages/index.ejs', {
            quotes: articles
        })
    })
})

我希望能够放置多个数据库查询,然后将多个数据变量传递给我的渲染,我的问题是,当我将res.render放在数据库查询之外时,它会尝试在数据库获取之前进行渲染它的数据集。

看看我的尝试如下:

//page load
app.get('/', (req, res) => {

    //find all data in test table
    var articles;
    db.collection('test').find().toArray((err, result) => {
        if (err) return console.log(err)
        articles = result
    })

        // renders index.ejs and passes result to quotes
        res.render('./pages/index.ejs', {
            quotes: articles
        })
})

我的问题是:

如何在运行db查询并将数据返回到变量后确保渲染发生 ONLY

  

最终我希望能够做到这样的事情:

//page load
app.get('/', (req, res) => {

    //find all data in table 1
    var AAA;
    db.collection('test1').find().toArray((err, result) => {
        if (err) return console.log(err)
        AAA = result
    })

     //find all data in table 2
    var BBB;
    db.collection('test2').find().toArray((err, result) => {
        if (err) return console.log(err)
        BBB = result
    })

     //find all data in table 3
    var CCC;
    db.collection('test3').find().toArray((err, result) => {
        if (err) return console.log(err)
        CCC = result
    })

        // renders index.ejs and passes result to quotes
        res.render('./pages/index.ejs', {
            quotes: AAA,
            quotes2: BBB,
            quotes3: CCC
        })
})

对此有任何帮助或建议表示赞赏。提前谢谢。

2 个答案:

答案 0 :(得分:2)

您可以使用async模块。将async.parallel用于彼此独立的函数,并使用async.series作为依赖进程。检查async

答案 1 :(得分:2)

试试这段代码,它没有经过测试,但我认为它应该可行:

app.get('/', (req, res) => {

    var list = {};

    db.collection('test').find().toArray().then(result => {
        list.result = result;
    }).then(() => {
        return Promise.resolve(db.collection('foo').find().toArray());
    }).then(result2 => {
        list.result2 = result2;
    }).then(() => {
        return Promise.resolve(db.collection('bar').find().toArray());
    }).then(result3 => {
        list.result3 = result3;
    }).then(() => {
        res.render('./pages/index.ejs', list);
    }).catch(e => {
        console.error(e);
    });

});

更新:我们可以对任何返回Promise的方法使用async / await,这样代码就会更清晰:

// you can use express-async-errors package to make routes async
app.get('/', async(req, res) => {
    let list = [];
    list.result = await db.collection('test').find().toArray();
    list.result2 = await db.collection('foo').find().toArray();
    list.result3 = await db.collection('bar').find().toArray();
    res.render('./pages/index.ejs', list);
});