2016-02-05 1 views
-1

Работа с Узлом и Экспрессом с Вавилонкой и попытка найти оптимальный подход между асинхронным/ожиданием и обещаниями.Узел и async/ждут, обещает ... какое решение лучше?

Основные требования:

  • , чтобы быть в состоянии передать свою собственную ошибку
  • не вызывают блокирование
  • подойти к проблеме более ES6/ES7 путь

Я вышел с эти:

Посылы:

loadByIdPromises: function (req, res, next, _id) { 
    console.log('loadByIdc: ', _id); 
    Artwork.loadById({ _id }) 
    .then((artwork) => { 
     req.artwork = artwork; 
     next(); 
    }) 
    .catch((err) => next(new NoDataError('cannot find by ID'))); 
} 

Асинхронный/Await:

loadByIdAsync: async function (req, res, next, _id) { 
    console.log('loadByIdb: ', _id); 
    try { 
    req.artwork = await Artwork.loadById({ _id }); 
    next(); 
    } catch (err) { 
    next(new NoDataError('cannot find by ID')); 
    } 
} 

или Асинхронный/Await с оболочкой

let wrap = fn => (...args) => fn(...args).catch(args[2]); 
loadByIdAsyncWrap: wrap(async function (req, res, next, _id) { 
    console.log('loadByIda: ', _id); 
    req.artwork = await Artwork.loadById({ _id }); 
    next(); 
}), 

Обещания, кажется чистым, но может привести к каскадные, когда дела идут сложнее. Но имеет хорошую и чистую обработку ошибок.

Async/Await кажется чистым, но я не могу понять, как выбросить ошибку из ждущего другого пути, чем вся попытка try/catch.

Async/Await with wrapper кажется простым и (по крайней мере, в этом случае - маршрутизатором с узлом-экспрессом) хорошо обрабатывает ошибку (но без возможности установить мой собственный). Но обертка специфична для req, res, следующих параметров, и мне кажется, что это нечто чужое (как дополнительные divs в html до нашего блаженства css2/3).

Какой подход выбрать? Спасибо за предложения.

+0

Вы посмотрели на koa: https://github.com/koajs/koa? –

+0

у вас есть потенциальная проблема в вашей версии на основе Promise и, возможно, в других - любое исключение, вызванное вызовом 'next()', может закончиться распространением резервной копии цепочки. Вероятно, вы хотите «load(), затем (do_stuff). Then (next, (err) => next (new Error))' – Alnitak

+1

Что не так с использованием 'try' /' catch' для обработки ошибок? –

ответ

1

Я бы использовал подход Promise, так как async/await еще не находится рядом с мейнстримом.

Однако я вижу потенциальную проблему в том, что ваш вызов next() является внутри начальный блок означает, что вы могли бы иметь успешный первый этап, а затем вызвать next(), но если что выдает ошибку, что не пойманный стек вызовов вернется на уровень, и эта ошибка попадает в ваш первый блок .catch(). Тогда вы создадите ошибку cannot find by ID, хотя реальная ошибка была в обработчике next().

Я хотел бы предложить это, вместо того, чтобы:

function (req, res, next, _id) { 
    console.log('loadByIdc: ', _id); 
    Artwork.loadById({ _id }) 
    .then((artwork) => req.artwork = artwork) 
    .then(next, (err) => next(new NoDataError('cannot find by ID'))); 
} 

Это все еще оставляет вас с вопросом, как над .catch любое исключение, которое может быть выброшено на next, но, по крайней мере, вы не будете вводить в заблуждение точкой при котором это исключение поймано.

+0

Аспект обработки ошибок является новым для меня, спасибо @Alnitak. Я бы поднял ваш ответ, но не могу. – DavidC

+0

* «Это все еще оставляет вам вопрос о том, как .catch любое исключение, которое может быть выбрано' next' * *. Оно будет поймано и превращено в отказ в обещании, возвращенном 'then'. Приведенный выше код должен либо обрабатывать отклонения (через '.catch (err => ...)'), либо передавать цепочку обещаний тому, что делает. Простейший способ (если не передать его) состоит в том, чтобы переместить второй обработчик, переданный этому финальному '.then', в следующий' .catch' вместо этого, поэтому он обрабатывает это отклонение, вызванное броском 'next'. (cc @DavidC) –

+0

@ T.J.Crowder не стесняйтесь обновлять, если хотите – Alnitak

Смежные вопросы