Когда вы используете await
при вызове функции, вы в основном ожидаете разрешения внутри этой функции. Вызванная функция предназначена для возврата этого обещания .
. В вашем коде функция login
действительно вызывает connection.query
, но нет никакого обещания, которое ожидает запрос кразрешить.
Чтобы заставить await
действительно ждать connection.query
, вам нужно вернуть Обещание, которое разрешается всякий раз, когда пользователь наконец входит в систему - т.е. у вас есть токен:
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 предназначен для работы с обещаниями. Асинхронные функции в JavaScript либо принимают обратный вызов, либо возвращают обещание.
connection.query
принимает обратный вызов, поэтому await
здесь бесполезен. - Скорее всего, модуль, который вы используете для общения с базой данных - mongoose? - имеет многообещающий API. Проверьте это, потому что, если вы хотите использовать async / await, лучше работать напрямую с Promises, а не заключать код в новое Promise.
Например, если connection.query
вернул aОбещай, ты мог бы сделать что-то вроде:
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 - как в моем примере - я не знаю, лучше ли будет
reject
или
throw
Ошибка. Я думаю, что оба будут делать то же самое, но я не уверен.