【发布时间】:2016-05-15 12:08:26
【问题描述】:
使用 Node 和 Express 与 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();
}),
Promise 看起来很干净,但当事情变得复杂时可能会导致级联。但是有一个漂亮而干净的错误处理。
Async/Await 看起来很干净,但除了整个 try/catch 之外,我不知道如何从 await 中抛出错误。
带有包装器的异步/等待似乎很简单,并且(至少在这种情况下 - 节点快速路由器)可以很好地处理错误(但无法设置我自己的)。但是包装器是特定于 req,res,next 参数的,在我看来它是一些外来的东西(比如我们的 css2/3 幸福之前的 html 中的额外 div)。
选择什么方法?感谢您的建议。
【问题讨论】:
-
你看koa了吗:github.com/koajs/koa?
-
您在基于 Promise 的版本中可能存在潜在问题,也许在其他版本中 - 调用
next()时引发的任何异常都可能最终传播到链上。你可能想要load().then(do_stuff).then(next, (err) => next(new Error)) -
使用
try/catch进行错误处理有什么问题? -
@Sergey_Ksenofontov 是的,我已经看过了,它看起来很棒,但我想和大多数人在一起(表达):)
-
谢谢@Alnitak 我知道了。我必须将
next()从.then(do_stuff)块移动到最后一个.then,对吗? wrap 函数暴露了我手动做的同样的问题,对吧?
标签: javascript node.js asynchronous promise