Pull to refresh

Comments 6

Не надо так демонизировать промисы, поверх которых 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 уже в браузерах, то это не повод забыть про промисы, а наоборот, повод лучше в них разобраться ибо они никуда не уйдут.

Ещё проще
example.firstAsyncRequest()
.then(example.secondAsyncRequest)
и так далее…

Сначала скептически отсесся к 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);
});

p.s. конечно же не err.sendStatuc(500);, а res.sendStatus(500);. К сожалению, кончилось время редактирования, и пишу комментарием.

спасибо, эта статья мне окончательно открыла глаза на async/await
Sign up to leave a comment.