我不明白这个东西是如何工作的。 谁能解释一下。
'
module.exports = (thefunc) => (req,res,next)=>{
Promise.resolve(thefunc(req,res,next)).catch(next)
}
'
我在网上搜索,仍然无法理解。
这个结构的要点:
Promise.resolve(thefunc(req,res,next)).catch(next)
是捕获任何可能从调用中返回的被拒绝的承诺:
thefunc(req,res,next)
并且,直接拒绝原因致电next(err)
。 它被包装在Promise.resolve()
中,以防thefunc(req,res,next)
根本不返回承诺(也许甚至什么都不返回)。 这使得添加.catch()
的类型安全。
这会尝试向路由引擎添加一些承诺感知,因为 Express 本身没有路由处理程序的承诺感知。
因此,这将适用于thefunc()
中的任何这些情况:
async function(req, res, next) {
if (!req.body.username) throw new Error("User Missing");
....
}
在这种情况下,这里的函数使用被声明为async
所以当它使用throw
时,这将导致它拒绝它返回的承诺。 然后,这将最终调用next(err)
其中err
是我们在那里创建的 Error 对象。
function(req, res, next) {
return queryMyDb(...).then(result => {
res.send(result);
});
}
在这种情况下,如果数据库查询拒绝,则此函数将返回拒绝的承诺,并且拒绝原因将发送给next(err)
就像包装器在前面的示例中一样。
function(req, res, next) {
res.send({cntr: req.body.cntr++});
}
虽然此请求处理程序不会导致任何类型的错误(假设req.body.cntr
有效),但它也不会返回承诺。 但是,由于函数调用被包装在Promise.resolve(theFunc(...))
中,该仍然允许包装器使用实际上不会发挥作用的.catch()
,因为此处没有发生错误,但是添加.catch()
不会因为Promise.resolve()
包装器而导致运行时错误。
注意,如图所示的包装器不会捕获路由处理程序中引发的同步异常,除非路由处理程序被声明为async
(这会自动将同步异常转换为被拒绝的承诺)。
如果还想捕获同步异常(通常建议),可以将其修改为:
module.exports = (thefunc) => (req,res,next)=>{
try {
Promise.resolve(thefunc(req,res,next)).catch(next)
} catch(e) {
next(e);
}
}
虽然,在这一点上,我可能会这样做:
module.exports = async (thefunc) => (req,res,next)=>{
try {
await thefunc(req,res,next);
} catch(e) {
next(e);
}
}
由于在非承诺上使用await
是无害的,因此在使用这样的await
时,您不必用Promise.resolve()
包裹。 如果thefunc()
碰巧返回拒绝或碰巧同步抛出的承诺,则try/catch
将捕获其中任何一个。