You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么在mysql的connection.query上使用await未达到同步效果?

错误原因

  • Array.prototype.forEach 不支持异步函数串行执行,传入的async回调会被并发触发,不会等待前一个回调内的await执行完成再执行下一个,因此所有nr日志会先批量打印,之后才陆续返回查询结果。
  • 直接await callback形式的connection.query无效,callback风格的API返回值不是Promise,await仅对Promise类型生效。
  • 自定义的queryPromise存在语法错误:if(err)分支结构书写错误,导致reject逻辑无论是否报错都会执行;Promise构造函数前缀的async属于冗余写法,没有实际作用。

修复方案

1. 修正queryPromise封装

const queryPromise = (
    connection: Connection,
    query: string,
    value: (string | number) []
) => {
    return new Promise((resolve, reject) => {
        connection.query(query, value, function (err, result) {
            if (err) {
                console.log("err: ", err, " result: ", result);
                return reject(err);
            }
            return resolve(result);
        });
    });
}

2. 替换forEach为支持异步串行的for...of循环

如果需要按用户顺序逐个执行查询(前一个查询结束后再执行下一个),使用如下写法(注意await必须放在async函数内部):

let users: number [] = [1, 2, 3]

async function runSerialQueries() {
    for (const usernr of users) {
        console.log("nr:" + usernr)
        try {
            // 用参数占位符?传值,避免SQL注入风险,不要直接拼接SQL字符串
            const result = await queryPromise(connection, "select count(*) from documents where userid = ?", [usernr])
            console.log("result: ", result, " nr: ", usernr);
        } catch (err) {
            console.log("err: ", err, " nr: ", usernr);
        }
    }
}

runSerialQueries()

执行后输出为预期的串行结果:

nr:1
result:  [ RowDataPacket { 'count(*)': 10 } ]  nr:  1
nr:2
result:  [ RowDataPacket { 'count(*)': 20 } ]  nr:  2
nr:3
result:  [ RowDataPacket { 'count(*)': 30 } ]  nr:  3

3. 可选:并行查询统一处理结果

如果不需要严格按顺序执行,仅需要所有查询完成后统一处理结果,可使用Promise.all提升执行效率:

async function runParallelQueries() {
    const queryTasks = users.map(async usernr => {
        const result = await queryPromise(connection, "select count(*) from documents where userid = ?", [usernr])
        return { usernr, result }
    })
    const allResults = await Promise.all(queryTasks)
    allResults.forEach(({usernr, result}) => {
        console.log("result: ", result, " nr: ", usernr)
    })
}

runParallelQueries()

内容的提问来源于stack exchange,提问作者Gerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 07:15:04