如何保持等待嵌套函数将值返回给父函数

问题描述 投票:1回答:1

下面是一段代码。我总是得到valid变量的初始值,因为最后一次返回语句在数据库查询完全执行之前运行

async login(username, password, ctx) {
        let sql = 'SELECT * FROM users WHERE username=?;'

        let valid = false; //I'm always getting this value

        await this.db.query(sql, [username], function(err, rows, fields){
            console.log(rows);
            if(rows.length > 0)
            {
                console.log('coming into');
                console.log(JSON.stringify(rows));
                valid = bcrypt.compare(password, rows[0].pass)
                console.log('valid is ', valid);    
                if(valid === false) throw new Error(`invalid password for account "${username}"`)
                ctx.session.user_id = rows[0].id
                ctx.session.authorised = true
                return ctx.redirect(`/secure?msg=you are now logged in...`)
            }
            else
                throw new Error(`username ${username} not found ${JSON.stringify(rows)}`);

            return valid;
        });

    }
javascript node.js function async-await callback
1个回答
1
投票

解决此问题的一种方法是将db调用包装在一个Promise中,然后等待该Promise解析/拒绝。然后,您可以设置授权标志并重定向用户或处理错误:

async login(username, password, ctx) {

    try {
        const rows = await new Promise((resolve, reject) => {
            let sql = 'SELECT * FROM users WHERE username=?;'
                this.db.query(sql, [username], function (err, rows, fields) {
                    console.log(rows);
                    if (rows.length > 0) {
                        console.log('coming into');
                        console.log(JSON.stringify(rows));
                        valid = bcrypt.compare(password, rows[0].pass)
                        console.log('valid is ', valid);
                        if (valid === false) {
                            reject(new Error(`invalid password for account "${username}"`));
                        }
                        return resolve(rows);
                    }
                    reject(new Error(`username ${username} not found ${JSON.stringify(rows)}`); )
                });

        });
        ctx.session.user_id = rows[0].id
        ctx.session.authorised = true
        return ctx.redirect(`/secure?msg=you are now logged in...`)
    } catch (err) {
        // handle your error, e.g. ctx.redirect('/error-page')
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.