异步等待调用函数 node.js

async await calling function node.js

我有这个函数,它查询我的数据库,然后调用 getNumOfSessionForTrainerClientList 函数:

var select = "select * from USERS WHERE ASSIGNED_TRAINER = ?"
mysqlconn.connect(function(err) {
    if (err) {
        console.error('Database connection failed: ' + err.stack);
        return;
    }

    mysqlconn.query(select, [req.session.username], async function(err, rows) {
        if (err) {
            console.log(err);
        } else {
            
            let numOfSessionsLeft = {
                numberOfSessionsLeftIs: 0
            }
            for (var i = 0; i < rows.length; i++) {
                getNumOfSessionForTrainerClientList(req, res, rows[i], numOfSessionsLeft)
                rows[i]["NUM_OF_SESSIONS_PER_MONTH"] = (parseInt(rows[i]["NUM_OF_SESSIONS_PER_MONTH"]) - numOfSessionsLeft.numberOfSessionsLeftIs)
                console.log(numOfSessionsLeft)
            }
          

        }
        mysqlconn.end();

    })
})

然后在函数 getNumOfSessionForTrainerClientList 中,我有这个:

async function getNumOfSessionForTrainerClientList(req, res, rows, numOfSessionsLeft) {

var getNumOfSessionForTrainerClientList = "select * from SCHEDULE WHERE CLIENT_USERNAME = ? AND ASSIGNED_TRAINER = ?"
mysqlconn.connect(async function(err) {
    if (err) {
        console.error('Database connection failed: ' + err.stack);
        return;
    }
        mysqlconn.query(getNumOfSessionForTrainerClientList, [rows["USERNAME"], req.session.username], async function(err, sessionData) {
            if (err) {
                console.log(err);
            } else {
                numOfSessionsLeft.numberOfSessionsLeftIs = 1;
                console.log(numOfSessionsLeft.numberOfSessionsLeftIs)

            }

        })

})

}

然而,发生的事情是这一行:rows[i]["NUM_OF_SESSIONS_PER_MONTH"] = (parseInt(rows[i]["NUM_OF_SESSIONS_PER_MONTH"]) - numOfSessionsLeft.numberOfSessionsLeftIs) 实际上是将 0 分配给 rows[i]["NUM_OF_SESSIONS_PER_MONTH"] 因为该变量分配发生在 getNumOfSessionForTrainerClientList 的函数调用之前完成。所以它的发生不同步。我不确定如何解决这个问题,我之前 运行 遇到过 async await 的问题,但没有这样的。非常感谢您的帮助。

你调用了包含异步代码的函数,因此 getNumOfSessionForTrainerClientList 不依赖于上面的代码(从(行[i][[NUM_OF 和控制台开始)你应该做的是

  1. 通过返回 prom 使函数异步

  2. 用 await 关键字执行它

    async function trainerClientList(){
    
    return new Promise((resolve,reject)=>{
    
                var getNumOfSessionForTrainerClientList = "select * from SCHEDULE WHERE CLIENT_USERNAME = ? AND ASSIGNED_TRAINER = ?"
        mysqlconn.connect(async function(err) {
            if (err) {
                console.error('Database connection failed: ' + err.stack);
                resolve()
            }
                mysqlconn.query(getNumOfSessionForTrainerClientList, [rows["USERNAME"], req.session.username], async function(err, sessionData) {
                    if (err) {
                        console.log(err);
                    } else {
                        numOfSessionsLeft.numberOfSessionsLeftIs = 1;
                        console.log(numOfSessionsLeft.numberOfSessionsLeftIs)
    
                    }
    
                })
    
        })
    
        resolve()
    
    
    })
    

    }

    for (var i = 0; i < rows.length; i++) { 等待 trainerClientList() rows[i]["NUM_OF_SESSIONS_PER_MONTH"] = (parseInt(rows[i]["NUM_OF_SESSIONS_PER_MONTH"]) - numOfSessionsLeft.numberOfSessionsLeftIs) console.log(剩余会话数) }

For 循环本质上是同步的,因此不会等待您的方法 getNumOfSessionForTrainerClientList 到 return 继续迭代。

正确的做法是:

  1. 将您的代码放入异步块中,并在调用 getNumOfSessionForTrainerClientList 调用时使用 await()。
  2. 其次,你的函数getNumOfSessionForTrainerClientList应该 return一个承诺。

样本:

async function functionA() {
    var select = "select * from USERS WHERE ASSIGNED_TRAINER = ?"
    mysqlconn.connect(function(err) {
        if (err) {
            console.error('Database connection failed: ' + err.stack);
            return;
        }
    
        mysqlconn.query(select, [req.session.username], async function(err, rows) {
            if (err) {
                console.log(err);
            } else {
                
                let numOfSessionsLeft = {
                    numberOfSessionsLeftIs: 0
                }
                for (var i = 0; i < rows.length; i++) {
                    await getNumOfSessionForTrainerClientList(req, res, rows[i], numOfSessionsLeft)
                    rows[i]["NUM_OF_SESSIONS_PER_MONTH"] = (parseInt(rows[i]["NUM_OF_SESSIONS_PER_MONTH"]) - numOfSessionsLeft.numberOfSessionsLeftIs)
                    console.log(numOfSessionsLeft)
                }
            }
            mysqlconn.end();
        })
    })
}

您的函数 getNumOfSessionForTrainerClientList 应该如下所示:

async function getNumOfSessionForTrainerClientList(req, res, rows, numOfSessionsLeft) {

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

        var getNumOfSessionForTrainerClientList = "select * from SCHEDULE WHERE CLIENT_USERNAME = ? AND ASSIGNED_TRAINER = ?"
        mysqlconn.connect(async function(err) {
            if (err) {
                console.error('Database connection failed: ' + err.stack);
                return reject(err);
            }
                mysqlconn.query(getNumOfSessionForTrainerClientList, [rows["USERNAME"], req.session.username], async function(err, sessionData) {
                    if (err) {
                        console.log(err);
                        return reject(err);
                    } else {
                        numOfSessionsLeft.numberOfSessionsLeftIs = 1;
                        console.log(numOfSessionsLeft.numberOfSessionsLeftIs)
                        return resolve();

                    }
                })

        })
    })

}

然后使用您需要的任何参数调用 functionA()