Node.js中async/await的行为

3

考虑以下 Node.js Express 路由:

router.route('/user')

   .post(async function(req, res) {
       if(req.body.password === req.body.passwordConfirm) {
           try {
               var response = await userManager.addUser(req.body);
               res.status(201).send();
           } catch(err) {
               logger.error('POST /user failed with error: '+err);
               res.status(500).send({err:"something went wrong.."});
           }
       } else {
           res.status(400).send({err:'passwords do not match'});
       }
   })

以及userManager中对应的功能:

var userManager = function() {

    this.addUser = async function(userobject) {
        userobject.password_hash = await genHash(userobject.password_hash);
        var user = new User(userobject);
        return await user.save();
    };

};

module.exports = userManager;

我可以安全地假设,如果catch块中的代码没有运行,那么就没有错误吗?由于userManager.addUser及其内部的所有内容都返回promise,这些promise如果被拒绝,应该被catch块捕获。 或者我漏掉了什么,还是应该检查响应的有效性?

如果您在response变量中得到了某些内容,这意味着目前还没有错误。但是,例如res.status(201).send();仍然可能会抛出一些错误(在您的情况下它将是正常的,但让我们假设您在try块中有更多代码)。 - Jake
要明确一点:所谓的“something”指的是任何东西,甚至包括nullundefined - Jake
在这种情况下,Model.save()(mongoose)返回一个承诺,因此它永远不会为null或undefined。所以在这种情况下,就像你说的那样,我没问题。 - NG.
nullundefined并不是错误,除非你当然会throw nullreject(null) - jib
1个回答

1

是的,你可以安全地假设所有错误来自于await userManager.addUser(req.body)都被捕获了。

如果返回的Promise被拒绝并带有值x,那么await关键字将确保它会throw x

但这并不能确保在该函数调用之外没有错误,比如在你的catch中。

最佳实践:

post()不期望一个async回调函数,因此它会忽略你隐式返回的Promise。

所以当你传递一个时,请将try/catch包裹在所有内容周围,因为没有人可以上报错误:

router.route('/user').post(async function(req, res) {
    try {
        if (req.body.password === req.body.passwordConfirm) {
            try {
                var response = await userManager.addUser(req.body);
                res.status(201).send();
            } catch (err) {
                logger.error('POST /user failed with error: '+err);
                res.status(500).send({err:"something went wrong.."});
            }
        } else {
            res.status(400).send({err:'passwords do not match'});
        }
    } catch (err) {
        logger.error('POST /user fatal error: '+err);
    }
})

这样可以捕获所有编程错误,避免出现未处理的拒绝或静默情况。

或者更好的选择是,如果有选项,请编写一个期望异步函数的 post


我不确定是否接受这个问题,因为它被踩了,而我不知道原因。 - NG.
我也不知道。 - jib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接