【发布时间】:2018-10-07 09:47:54
【问题描述】:
假设我有这样的路线:
app.get('/broken', (req, res) => {
throw new Error('Broken!');
});
这永远不会向客户端发送响应。
但是,我可以为所有错误添加一个中间件:
const errorMiddleware = (error, req, res, next) => {
if (error) {
console.error(error);
return res.status(500)
.json({
message: 'Internal server error',
});
}
next(error);
};
但这不适用于async 路由,因为它们不直接throw。
例如,这将不起作用:
app.get('/broken', async (req, res) => {
throw new Error('Broken!');
});
所以我可以像这样创建一个包装器:
const asyncRoute = f => (req, res, next) => {
return Promise.resolve(f(req, res, next)).catch(next);
};
app.get('/broken', asyncRoute(async (req, res) => {
throw new Error('Broken!');
}));
但这真的很痛苦,因为现在我必须为每条路线调用这个函数!
有什么更好的方法来处理这个问题?
【问题讨论】:
-
你认为路由回调
async有什么好处? Express 不使用承诺,所以......纯粹是为了在其中获得await语义吗?如果是这样,您的包装器就是这样做的正确方法。 -
(你可以看看Koa。)
-
好吧,我的一些路由需要多次
async调用(例如数据库、API、bcrypt),因此在async上下文中更容易编写。 -
@T.J.Crowder 如果我没有通过承诺(例如
123),那么我希望强制承诺(例如Promise.resolve(123))。请注意,Promise.resolve(Promise.resolve(x))被展平为Promise.resolve(x)。 -
好的。我没有看到任何理由将非承诺传递给名为
asyncRoute的东西,所以我没有意识到你想要处理这个问题。 :-)
标签: javascript express async-await