在 Node.js res.render 中同时呈现两个不同查询的结果

Render results of two different queries at the same time in Node.js res.render

我试图在一页中显示两个 SQL 查询的结果。我的代码在 module.exports 块中,整个应用程序是用 Node.js Express 编写的。这 returns 一个错误 "Cannot read property 'length' of undefined"。

var message = "some random text";
var res_points, res_types;
    db.query(query, (err, result) => {
        if (err) {
            res.redirect('/');
        }
        res_points= result;
    });
    db.query(query2, (err, result) => {
        if(err) {
            res.redirect('/');
        }
        res_types = result;
    });

    res.render('index.ejs', {
        title: message,
        ,points: res_points
        ,types: res_types
    });

当我这样做时,它起作用了:

db.query(query, (err, result) => {
        if (err) {
            res.redirect('/');
        }
        res.render('index.ejs', {
            title: message,
            points: result
        });
    });

我做错了什么?或者更好地说,我如何将这两个查询的结果传递到渲染函数中?

我找到了这样的解决方法,但我真的不认为这是唯一、正确且优雅的方法:

    let res_points, res_types;
    db.query(query, (err, result) => {
        if (err) {
            res.redirect('/');
        }
        db.query(query2, (err2, result2) => {
            if(err2) {
                res.redirect('/');
            }
            res.render('index.ejs', {
                title: "Welcome to Hamburg Map | View Points"
                ,points: result
                ,types:result2
            });
        });
    });

这里最简洁的方法是使用 Promises & Promise.all。为此,您需要将 db.query 包装在 Promise.

// You can use Util.promisify too
const queryWrapper = (statement) => {

    return new Promise((resolve, reject) => {

        db.query(statement, (err, result) => {
            if(err)
                return reject(err);

            resolve(result);
        });

    });

};


app.get('/some-route', (req, res, next) => {
    const message = "some random text";

    Promise.all([
        queryWrapper(query),
        queryWrapper(query2)
    ])
    .then(([points, types]) => {

        res.render('index.ejs', {
            title: message,
            points,
            types
        });
    })
    .catch(err => {
        console.error(err);
        res.redirect('/');
    })
});

注意:如果您正在使用 MySQL,mysql2 包提供 promise 支持,因此您可以避免使用 Promise 包装器.