【问题标题】:Behaviour of async/await in Node.jsNode.js 中异步/等待的行为
【发布时间】:2017-11-02 02:17:25
【问题描述】:

给定以下 Node.js 快速路由:

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,如果被拒绝,应该被catch 块捕获。 还是我错过了什么,我还应该检查回复的有效性吗?

【问题讨论】:

  • 如果你在你的response 变量中得到了一些东西,这意味着没有错误。但是,例如res.status(201).send(); 仍然可以抛出一些(在您的情况下会很好,但假设您在try 块中有更多代码)。
  • 明确一点:我所说的“某事”是指任何事,甚至是nullundefined
  • 在这种情况下 Model.save() (mongoose) 返回一个承诺,因此它永远不会为空或未定义。所以在这种情况下,我会像你说的那样。
  • nullundefined 不是错误,除非您当然是 throw nullreject(null)

标签: node.js express promise async-await


【解决方案1】:

是的,您可以放心地假设所有错误来自await userManager.addUser(req.body)

如果返回的 Promise 以 x 的值被拒绝,则 await 关键字确保它会 throw x

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

最佳实践:

post() 不期望 async 回调函数,因此它会忽略您隐式返回的承诺。

因此,当您传递一个时,请将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,它需要一个异步函数。

【讨论】:

  • 我不愿接受这个问题,因为它被否决了,我不知道为什么......
  • 我也不知道。
猜你喜欢
  • 2021-11-14
  • 2021-03-26
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 2019-04-22
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多