无法理解 Promise.resolve 的语法,它被用来代替 try-catch 块



我不明白这个东西是如何工作的。 谁能解释一下。

'

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将捕获其中任何一个。

最新更新