асинхронность и ожидание и обещание в отношении перехвата ошибок
У меня есть вопрос о том, чтобы поймать ошибку пользователя в async и ждать.
Допустим, у меня есть маршрут, который выбирает только один пользователь.
Маршруты.js
routes.get('/getuserbyid/:id', (req, res) => {
const id = req.params.id;
accountController.getById(id)
.then((result) => {
res.json({
confirmation: 'success',
result: result
});
})
.catch((error) => {
res.json({
confirmation: 'failure',
error: error
});
});
});
У меня есть контроллер, который получает запрос. accountController.js
export const getById = async (id) => {
try {
const user = await users.findOne({ where: {
id: id
}});
if (user === null) {
return 'User does not exist';
}
return user;
} catch (error) {
return error;
}
}
Поэтому, что бы ни случилось, я получаю либо нулевую, либо единственную запись. Это все еще успех.
В обещаниях я могу отклонить null, поэтому он будет отображаться в блоке catch в маршруте. Теперь вот с асинхронностью и жду. Как я могу достичь то же самое делает null в блоке ошибок?
export const getById = (id) => {
return new Promise((resolve, reject) => {
users.findOne({ where: {
id: id
}})
.then((result) => {
if (result === null) {
reject('User does not exit');
}
resolve(result);
})
.catch((error) => {
reject(error);
});
});
}
3 ответа:
Во-первых, избегайте обещания антипаттерна. У вас есть функция, которая возвращает обещание, не нужно оборачивать это в
new Promise()
.Тогда ваша функция может выглядеть следующим образом:
export const getById = (id) => { return users.findOne({ where: { id } }) .then((user) => { if (user === null) throw 'User does not exit'; return user; }); }
И версия async / await этого является
export const getById = async (id) => { const user = await users.findOne({ where: { id } }); if(user === null) throw 'User does not exist'; return user; }
Функция
async
всегда возвращает aPromise
., используя конструкцию
throw
в функцииasync
, отклоняет возвращаемую функциюPromise
.Рассмотрим
function getValue() { return Promise.reject(null); } getValue().catch(e => { console.log('An raised by `getValue` was caught by a using the `.catch` method'); console.log(e); }); (async function main() { try { await getValue(); } catch (e) { console.log('An raised by `getValue` was caught by a catch block'); console.log(e); } }());
async function getValue() { throw null; } getValue().catch(e => { console.log('An raised by `getValue` was caught by a using the `.catch` method'); console.log(e); }); (async function main() { try { await getValue(); } catch (e) { console.log('An raised by `getValue` was caught by a catch block'); console.log(e); } }());
Блок
try
Внутри асинхронного метода обрабатываеткак синхронные, так и асинхронные ошибки.Рассмотрим
function throws() { throw Error('synchronous failure'); } async function rejects() { throw Error('asynchronous failure'); } (async function main() { try { throws(); } catch (e) { console.log('asynchronously handled', e.message); } try { await rejects(); } catch (e) { console.log('asynchronously handled', e.message); } }());
Критическим моментом, который следует иметь в виду, является то, что асинхронные ошибки не будут поймают, если вы забудете
await
обещание, которое отвергаете вместе с ними. Это аналог забыванияreturn
внутри.then
или.catch
обратного вызова