使用 Node 并与 Babel 合作,并试图找出 async/await 和 promise 之间的最佳方法。
关键要求:
- 能够通过我自己的错误
- 不会导致阻塞
- 以更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')));
}
异步/等待:
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'));
}
}
或使用包装器异步/等待
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 似乎很简单,并且(至少在这种情况下 - 节点快速路由器(可以很好地处理错误(但无法设置我自己的错误(。但是包装器特定于req,res,next参数,在我看来,它似乎是外来的东西(就像在我们的css2/3幸福之前html中的额外div(。
选择什么方法?感谢您的建议。
我会使用Promise方法,因为async / await
还没有接近主流。
但是,我看到了一个潜在的问题,因为您对next()
的调用位于初始块内,这意味着您可以成功进行第一阶段,然后调用next()
,但是如果抛出未捕获的错误,调用堆栈将返回一个级别,该错误被您的第一个.catch()
块捕获。 然后,即使真正的错误在next()
处理程序中,您也会生成该cannot find by ID
错误。
相反,我会建议这样做:
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
可能引发的任何异常,但至少您不会被捕获该异常的点误导。