我正在使用express js开发api,在我的api调用中我调用了2个函数,第一个是login()
,其他函数是get_organizations()
,但是get_organization()
在没有完成 login()
函数的情况下调用,我使用了 async wait 但它无法正常工作,有人可以帮我解决这个问题吗?我已在此处添加了整个代码,
router.get('/', async (req, res) => {
let token = await login();
await get_organizations(token);
});
const get_organizations = async function (api_token) {
try {
console.log('Get List Of Organizations');
console.log('Verifying token');
let verify_token_data = await jwt.verify(api_token, config['token-secret']);
console.log(verify_token_data);
return false;
} catch (error) {
console.log(error);
}
}
const login = async function () {
try {
console.log('Login process started');
const newToken = await jwt.sign({login:'login'},config['token-secret'],{ expiresIn: config['token-expires']});
let username = 'root_admin'
let password = 'Admin123';
let token = String(cryptojs.lib.WordArray.random(20));
console.log("token : "+token);
await connection.query('SELECT * FROM users where username = ? ',[username], async function(err, rows) {
if (err) {
console.log("Looged out failed");
} else {
const user = rows[0];
console.log("psdsdsd");
if(bcrypt.compareSync(password,user.passwordHash)) {
await connection.query('SELECT * FROM organizations where id = ? ',[user.organizationId], async function(err, org_data) {
if (err) {
console.log("Looged out failed");
} else {
console.log("sdsd");
//console.log(org_data);
if(typeof org_data.name!='undefined') {
organization = org_data.name;
} else {
organization = 'VeriCurious';
}
//console.log(organization);
// create a token
const token = await jwt.sign({ id: user.id, username: user.username, organizationId: user.organizationId, organization: organization}, config['token-secret'], {
expiresIn: config['token-expires'] // expires in 30 minutes
});
console.log("Successfull loggedin");
console.log("New generated token : "+token);
return token;
}
});
}
}
});
} catch (error) {
console.log(error);
}
}
最佳答案
当您在调用函数时使用 await
时,您基本上是在等待该函数内部的 Promise 得到解析。调用的函数旨在返回该 promise 。
在您的代码中,login
函数确实调用 connection.query
,但没有任何等待查询解析的 Promise。
为了让 await
真正等待 connection.query
,您需要返回一个 Promise,该 Promise 会在用户最终登录时解析 - 即您拥有 token :
const login = async function () {
try {
console.log('Login process started');
const newToken = await jwt.sign({login:'login'},config['token-secret'],{ expiresIn: config['token-expires']});
let username = 'root_admin'
let password = 'Admin123';
let token = String(cryptojs.lib.WordArray.random(20));
console.log("token : "+token);
return new Promise(function(resolve, reject){
connection.query('SELECT * FROM users where username = ? ',[username], async function(err, rows) { // await won't do anything here,
// you should only use await with functions that return promises.
if (err) {
console.log("Looged out failed");
throw new Error(err);
} else {
const user = rows[0];
console.log("psdsdsd");
if(bcrypt.compareSync(password,user.passwordHash)) {
await connection.query('SELECT * FROM organizations where id = ? ',[user.organizationId], async function(err, org_data) {
if (err) {
console.log("Looged out failed");
throw new Error(err);
} else {
console.log("sdsd");
//console.log(org_data);
if(typeof org_data.name!='undefined') {
organization = org_data.name;
} else {
organization = 'VeriCurious';
}
//console.log(organization);
// create a token
const token = await jwt.sign({ id: user.id, username: user.username, organizationId: user.organizationId, organization: organization}, config['token-secret'], {
expiresIn: config['token-expires'] // expires in 30 minutes
});
console.log("Successfull loggedin");
console.log("New generated token : "+token);
resolve(token); // this signals the Promise to resolve.
// return token;
}
});
}
}
});
});
} catch (error) {
console.log(error);
}
}
一些注意事项:
- Await 旨在与 Promise 配合使用。 JavaScript 中的异步函数,要么接受回调,要么返回 promise 。
connection.query
需要回调,因此await
在那里没有用。 - 您用来与数据库对话的模块 -mongoose? - 很可能有一个 promise 的 API。检查一下,因为如果您愿意使用 async/await,最好直接使用 Promise,而不是将代码包装在新的 Promise 中。
例如,如果connection.query
返回一个Promise,你可以这样做:
const login = async function () {
// skipped a lot of code and logic since this is an example
const rows = await connection.query('SELECT * FROM users where username = ? ',[username]);
const user = rows[0];
const org_data = await connection.query('SELECT * FROM organizations where id = ? ',[user.organizationId]);
const organization = org_data.name;
return await jwt.sign({ id: user.id, username: user.username, organizationId: user.organizationId, organization: organization}, config['token-secret'], {
expiresIn: config['token-expires'] // expires in 30 minutes
});
}
处理错误非常简单。
- 当您在
async
函数内的回调中遇到错误,并且返回一个新的 Promise 时(就像在我的示例中一样),我真的不知道是拒绝
还是抛出
错误更好。我认为两者都会做同样的事情,但我不确定。
关于node.js - 为什么我的异步等待无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58264832/