【问题标题】:Using NodeJS and MySQL, await/async functions sometimes not waiting for query to finish使用 NodeJS 和 MySQL,await/async 函数有时不等待查询完成
【发布时间】:2020-08-09 05:49:07
【问题描述】:

我有两个异步函数,

async function sqlPushSteamappid(appId){
    let tmp;
    let sql='INSERT INTO cleetusbot.tmp (appId) VALUES ('+appId+');';
    tmp = new Promise((res, rej) => {
        global.pool.query(sql, function (err, results, fields) {    
            if(err){
                console.log(err);
            }
        });
    });
    return await tmp;
}

async function sqlGetSteamNames(){
    let tmp;
    let sql='SELECT * FROM cleetusbot.steamGames INNER JOIN tmp ON cleetusbot.steamGames.appId = cleetusbot.tmp.appId;';
    tmp = new Promise((res, rej) => {
        global.pool.query(sql,function (err, results, fields) {    
            if(err){
                console.log(err);
            }
            res(results);
        });
    });
    await tmp;
    return tmp;
}

两者都返回我需要的东西,但是大多数时候,当它们被称为 MySQL 查询时,它们要么没有完全返回,要么没有在承诺内返回答案。我是否在代码中遗漏了某些内容,或者我是否必须延长 MySQL 超时时间? 这是我在代码中调用它们的方式:

for(let i = 0; i < gameList.length; i++){
                sqlPushSteamappid(gameList[i]);
            }
            //sometimes does not return anything
            let steamNameObj = await sqlGetSteamNames();

【问题讨论】:

    标签: javascript mysql node.js


    【解决方案1】:

    首先你应该明白为什么事情会以他们在你的 sn-p 中的方式发生。

    根本别想你的mysql,那些异步调用的行为和其他的一样;还要考虑到 for 迭代本身是异步的,这意味着 for 内部的所有函数调用都将被调用,而无需等待前一个完成(即使您 await 他们)。 sqlGetSteamNames() 也将在您的所有 sqlPushSteamappid() 被调用后立即被调用(同样,无需等待它们完成)。

    您需要摆脱执行顺序的不确定性,您可以让您的sqlPushSteamappid() 返回一个承诺,并使用Promise.all (docs here) 来协调您的请求。所以首先在Promise.all 中输入你所有的sqlPushSteamappid(),然后在它返回后,你可以像在代码中那样调用await sqlGetSteamNames()

    工作示例:

    const promises = [
        new Promise((resolve, reject) => {
            setTimeout(() => resolve("3 sec passed"), 3000);
        }),
        new Promise((resolve, reject) => {
            setTimeout(() => resolve("2 sec passed"), 2000);
        }),
        new Promise((resolve, reject) => {
            setTimeout(() => resolve("4 sec passed"), 4000);
        })
    ];
    
    const ending = async () => { setTimeout(() => { console.log("2 sec to finish") }, 1000); }
    
    const start = async () => {
        const results = await Promise.all(promises);
        console.log(results);
        await ending();
    }
    
    start();
    

    【讨论】:

      猜你喜欢
      • 2018-09-23
      • 2019-04-08
      • 1970-01-01
      • 2021-01-26
      • 2021-02-10
      • 2020-08-03
      • 1970-01-01
      • 2017-09-11
      • 1970-01-01
      相关资源
      最近更新 更多