首页 > 解决方案 > Node JS 等待一系列 mysql 查询

问题描述

我正在使用 mysql 和 Node JS 开发一个 RESTful API。我在定义为的选择函数中将查询包装到数据库中:

var mysql = require('mysql');

var db = mysql.createConnection({
host     : CONFIG.db_host,
user     : CONFIG.db_user,
password : CONFIG.db_password,
database : CONFIG.db_name
});

function select(query, callback, out, args) 
{
    console.log('Sent query: ' + query);
    db.query(query, args, function(err, rows){
        if(err) throw err;
        return callback(rows, out);
    });
};

为了在我的应用程序中实现一个功能,我必须对返回未确定行数 (N) 的数据库表执行查询,并使用在每一行中获得的信息对另一个执行 N 个新查询桌子。

就像是:

function callback(rows, out){

    // just to give the idea ...

    for(var i=0; i<rows.length; i++)
    {
       db.select("SELECT * FROM table WHERE col=?", function(rows, out){
           out.push(rows);
       }, rows[i].col)
    }  
    // wait for all queries ...

    console.log(out)
}

out = []
db.select("SELECT * FROM table WHERE col=?", callback, out, col)

异步运行所有查询没有问题,但我必须等待所有查询结束,然后才能返回我的 API 响应。我认为使用 Promises 可能是一种方式,但鉴于未确定的查询数量,我不知道如何实现它。你能帮助我吗?

标签: mysqlnode.jsrestasynchronous

解决方案


你的主要问题是for循环。使用它意味着您正在混合同步和异步代码。

如果您需要使用回调模式,我建议您还使用外部库,例如async,它可以更轻松地使用异步迭代模式。像下面这样的东西可能会奏效:

var async = require('async');

conn.query('SELECT * FROM table WHERE col=?', col, function (err, rows) {
    async.each(rows, function (row, callback) {
        conn.query('SELECT * FROM other_table WHERE col=?', row.col, callback);
    }, function () {
        // all queries are done
    })
});

如果你想使用 Promise,mysql2包提供了与mysql类似的 API ,但支持Promise。使用基于 - 的 API 的有趣之Promise处在于,您可以使用async/await(在 Node.js 上>= 7.6),如果您不喜欢常规 JavaScript 代码的异步特性,这会让您的生活变得更轻松。

因此,在您的情况下,您将能够执行以下操作:

var mysql = require('mysql2/promise');

async function main () {
    var conn = await mysql.createConnection({
        host     : CONFIG.db_host,
        user     : CONFIG.db_user,
        password : CONFIG.db_password,
        database : CONFIG.db_name
    });

    var [rows] = await conn.query('SELECT * FROM table WHERE col=?', col);
    var out = [];

    for (var row of rows) {
        var result = await db.query('SELECT * FROM other_table WHERE col=?', row.col);
        out.push(result);
    }

    // all queries are done
}

main();

推荐阅读