回调解决未处理的承诺,为啥?

Posted

技术标签:

【中文标题】回调解决未处理的承诺,为啥?【英文标题】:Callback to solve unhandled promise, why?回调解决未处理的承诺,为什么? 【发布时间】:2018-07-14 13:43:26 【问题描述】:

我已经解决了这个问题,所以我的问题更多是理论上的,因为我试图了解幕后发生的事情以及为什么我需要在

上进行回调
return Promise.reject()

这是我用来验证路由的代码

async customAuth(req, res, next) 
    let token = req.header('x-auth');
    try
        const userByToken = await User.findByToken(token)

        const userByCreator = await User.findOne(_id: req.body.creator)

        if (!userByToken || !userByCreator) 
            return Promise.reject()
                    

        else if(userByToken.tokens[0].token !== userByCreator.tokens[0].token)
            console.log('its here')
            return Promise.reject().catch((err)=>
                res.status(401).send('why do i need this callback?')
            )    
                      
        next()

    catch(err)res.status(401).send("something happened")

正如您在比较 userByToken 和 userByCreator 时看到的那样,我正在尝试使用回调调用 return Promise.reject()。 如果我尝试删除回调,它会在控制台中告诉我我有未处理的承诺。这很奇怪,因为这段代码

 if (!userByToken || !userByCreator) 
                return Promise.reject()
                        

工作得很好,并发送 try 块直接捕获而不给出未处理的承诺错误。

问题

为什么我必须进行回调?就像理论上一样,为什么如果我删除回调它会告诉我它未处理的承诺?

附言 看来问题也可以解决

const rejected = await customAuth(Promise.reject('promise was rejected'));
return rejected

但是为什么这段代码可以工作,

 if (!userByToken || !userByCreator) 
            return Promise.reject()
      

但是当我尝试放入比较 IF 块时,它说未处理?

【问题讨论】:

我不明白你说“我为什么要进行回调”或“Promise.reject() 带有回调”是什么意思? 您是否意识到return Promise.reject() 不会导致它转到此函数中的catch 块?这只是从这个函数返回一个被拒绝的承诺。现在,如果您选择了throw new Error("some error"),那将转到您的catch 块。 我的意思是为什么当我说 if(!userByToken)return Promise.reject() 效果很好但是如果我在比较它认为的令牌时尝试将相同的 return Promise.reject 放在 IF 块内为“不好,需要回调 你能告诉我们customAuth()是如何被调用的吗?如果你要返回一个被拒绝的承诺,那么这就是需要处理这些拒绝的地方。 只是把它作为一个函数放在路由中,问题肯定不存在。下面的答案给出了一个更具体的解释,我只是想知道我怎样才能通过第二次拒绝达到外部捕获 【参考方案1】:

我认为问题在于,当您执行return Promise.reject() 时,您希望您的代码进入您的catch() 块,但return Promise.reject() 只是从函数返回一个被拒绝的承诺。它不会进入你的 catch 块。相反,您可以像这样使用throw

async customAuth(req, res, next) 
    let token = req.header('x-auth');
    try 
        const userByToken = await User.findByToken(token)

        const userByCreator = await User.findOne(_id: req.body.creator)

        if (!userByToken || !userByCreator) 
            throw new Error("missing userByToken or userByCreator");
                    

        else if(userByToken.tokens[0].token !== userByCreator.tokens[0].token)
            console.log('its here')
            throw new Error("user token doesn't match creator token");
                      
        next()

     catch(err) 
        console.log(err);
        res.status(401).send("something happened");
    

您可能感到困惑的是,您的 try/catch 会捕获您正在使用 await 的被拒绝承诺,或者它会捕获 throw,但它不会捕获 return Promise.reject(),因为您明确返回那个。

因此,当您执行return Promise.reject() 并因此返回一个被拒绝的承诺并且调用者没有.catch() 时,您会得到一个未处理的被拒绝承诺。

【讨论】:

嗯很有趣。谢谢你的解释,非常感谢【参考方案2】:

对不起,我错了

Promise.reject()

try / catch 抓不到, 它只能被 somePromise.cateh(() => ),

如果你想在外层捕获它, 只要throw new Error()就可以了, 不需要return or promise.reject

【讨论】:

以上是关于回调解决未处理的承诺,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

为啥一个已解决的承诺仍处于待处理状态?

如何解决未处理的承诺拒绝?

未处理的承诺警告。如何解决?

即使处理完所有案件,承诺仍未解决

解决一堆承诺时出现 Firebase 错误:无法将未定义或 null 转换为对象

如何解决该错误>> WARN可能的未处理承诺拒绝(id:0):