Комментарии 6
Не надо так демонизировать промисы, поверх которых async/await работает. Ваш пример с пирамидой ужаса можно записать так:
Пирамида ужаса это скорее про коллбеки.
Это я к тому, что раз async/await уже в браузерах, то это не повод забыть про промисы, а наоборот, повод лучше в них разобраться ибо они никуда не уйдут.
const example = require('example-library');
example.firstAsyncRequest()
.then( fistResponse => example.secondAsyncRequest(fistResponse) )
.then( secondResponse => example.thirdAsyncRequest(secondResponse) )
.then( thirdAsyncResponse => // никакого безумия!!!!11 )
//а теперь можно и глобальный catch на все три операции поставить
.catch( err => handleError(err) );
Пирамида ужаса это скорее про коллбеки.
Это я к тому, что раз async/await уже в браузерах, то это не повод забыть про промисы, а наоборот, повод лучше в них разобраться ибо они никуда не уйдут.
Сначала скептически отсесся к async / await, когда вышла спецификация. Но теперь проект полностью был переписан с этой технологией. И да, код действительно стал проще и читабельнее. Моя рекомендация — однозначно использовать.
Зачем ради одной проверки на null
копировать все поля? Не лучше ли было бы
сделать так:
// API
router.get('/words', async (req, res) => {
const {userId} = req.query;
const wordsSnapshot = await db.ref(`words/${userId}`).once('value');
// Еще лучше
const response = snapshot.val() || {};
res.send(response);
});
Касаемо асинхронных функций в Express роутере, попробуйте сделать так (я не
думаю, что вы дождетесь ответа. Даже от обработчика ошибок):
router.get('/words', async (req, res) => {
noSuchMethod(); // <=
res.send({});
});
router.use((err, req, res, next) => {
console.error(err);
err.sendStatuc(500);
});
А исправить это можно вполне легко:
function isPromise(obj) {
if (!obj || !obj.constructor) {
return false;
}
if (obj.constructor.name === 'Promise'
|| obj.constructor.displayName === 'Promise') {
return true;
}
return (typeof obj.then === 'function' || typeof obj.catch === 'function');
}
function wrap(fn) {
const { length } = fn;
if (length < 4) {
return (req, res, next) => {
const result = fn(req, res, next);
return isPromise(result) ? result.catch(next) : result;
};
} else {
return (err, req, res, next) => {
const result = fn(err, req, res, next);
return isPromise(result) ? result.catch(next) : result;
};
}
};
router.get('/words', wrap(async (req, res) => {
noSuchMethod(); // <=
res.send({});
}));
router.use((err, req, res, next) => {
console.error(err); // Вот теперь сюда свалится ошибка
err.sendStatuc(500);
});
спасибо, эта статья мне окончательно открыла глаза на async/await
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Пишем симпатичные Node.js-API с использованием async/await и базы данных Firebase