承诺(然后-捕获)或异步/等待(使用Try-Catch)进行异常控制

时间:2019-08-29 00:25:00

标签: node.js async-await try-catch

我想知道如何在async / await中工作,如果在async / await中尝试捕获更方便,或者仅在不使用async-await的情况下仅与then-catch一起使用promises

我在Node JS和Express中有这个小代码作为示例,可以更好地理解:

const { validationResult } = require('express-validator');
const Post = require('../models/post');

module.exports = {

    //HTTP POST Method

    createPost: async(req, res, next) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(422).json({
                errors: errors.array()[0].msg
            });
        }

        try {
            const { title, content, imageUrl } = req.body;

            const newPost = new Post({
                title,
                content,
                imageUrl
            });

            const post = await newPost.save();

            if (!post) {
                return res.status(422).json({
                    errors: 'Error'
                });
            }

            return res.status(201).json({
                message: 'Post created successfully!',
                post: {
                    title: title,
                    content: content,
                    image: imageUrl,
                }
            });

        } catch (err) {
            return res.status(500).json({
                errors: 'Error'
            });
        }
    }
}

感谢您的时间!

1 个答案:

答案 0 :(得分:1)

由于您没有提出非常具体的问题,因此,我会在您的代码中给您一些注释和替代方法。但首先要注意以下几点:

使用asyncawait进行编程是可选的。何时使用它部分是意见,部分取决于您在做什么。如果您只有一个异步操作是代码流的一部分,那么通常没有特别的理由使用await的吸引力较小,因为简单的.then().catch()try/catch的复杂性。

如果您有捕获需要同步引发的异常的危险,那么无论如何,无论如何,您都必须使用try/catch


现在,这里有一些关于您的代码的注释:

在此代码段中:

       const post = await newPost.save();

        if (!post) {
            return res.status(422).json({
                errors: 'Error'
            });
        }

如果newPost.save()操作失败,则它将拒绝承诺。如果它拒绝了承诺,那么,因为您正在使用await,所以拒绝将进入您的catch()处理程序,因此它根本不会到达if (!post) ...块。如果该支票曾经有用,我会感到惊讶。

由于您的控制流中只有一个异步操作,并且我看不到同步引发异常的任何危险,因此我可能会像这样使用.then().catch()

const { validationResult } = require('express-validator');
const Post = require('../models/post');

module.exports = {

    //HTTP POST Method

    createPost: (req, res, next) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(422).json({
                errors: errors.array()[0].msg
            });
        }

        const { title, content, imageUrl } = req.body;

        const newPost = new Post({
            title,
            content,
            imageUrl
        });

        newPost.save().then(post => {
            res.status(201).json({
                message: 'Post created successfully!',
                post: {
                    title: title,
                    content: content,
                    image: imageUrl,
                }
            });
        }).catch(err => {
            res.status(500).json({
                errors: 'Error'
            });
        });
    }
}
  

我想知道如何在async / await中工作,如果在async / await中尝试捕获更方便,或者只在不使用async-await的情况下使用promise,那么只能在then和catch中使用promise。

没有统一的准则。如果控制流中只有一个异步操作,则使用.then().catch()。如果我有多个异步操作,并且需要进行序列化(一个接一个),那么我将使用async/await。那只是我的个人风格,也是我发现最干净,最方便的东西。在其他情况下,async函数仅用作默认的catch处理程序,因此任何同步引发的异常都会自动转换为对调用方的拒绝,并且在某些情况下,函数内部同步和异步流的混合,有时执行可能是完全同步的。将其自动包装到async函数中可确保该接口始终返回promise,即使在某些条件下执行是完全同步的也是如此。

这在缓存中经常出现。如果该值在缓存中,则检索它是完全同步的,但是无论如何,您的接口都需要返回一个Promise。 async函数将自动为您执行此操作。可以通过执行return Promise.resolve(cachedValue)来手动编写此代码,但是有时async函数对于这种情况来说更干净。