在try catch中包装异步等待查询

时间:2017-11-16 03:00:35

标签: node.js asynchronous async-await

我最初在我的getAllUsers方法中使用try...catch进行查询,但最终删除了它,因为据我所知,它没有做任何事情。我知道async函数返回一个promise,所以它应该很好,实际上是基于代码的结构,我认为它是必需的,否则查询中的try...catch会吞下错误。这个结构和使用async/awaittry...catch.then .catch是否有任何遗漏?

let getAllUsers = async () => {
  let res = await models.users.findAll({
      attributes: [ 'firstName', 'lastName' ]
    });
    return res;
};

router.get(`${path}`, (req, res) => {
    queries.users.getAllUsers()
      .then(users => {
        res.status(200).json(users);
      })
      .catch(error => {
        res.status(500).send(error)
      });
});

3 个答案:

答案 0 :(得分:2)

根本没有理由在你的函数中使用await。而不是:

let getAllUsers = async () => {
    let res = await models.users.findAll({
      attributes: [ 'firstName', 'lastName' ]
    });
    return res;
};

可能就是这样:

let getAllUsers = () => {
    return models.users.findAll({
      attributes: [ 'firstName', 'lastName' ]
    });
};

您只需直接返回承诺,调用者就会使用与您相同的承诺。由于您未在getAllUsers()函数中使用结果或与其他任何内容进行协调,因此没有理由使用await。并且,由于没有使用await,因此没有理由将函数声明为async

如果您想使用await,可以将其用于getAllUsers()的来电者:

router.get(`${path}`, async (req, res) => {
    try {
        let users = await queries.users.getAllUsers();
        res.status(200).json(users);
    } catch(error => {
        res.status(500).json(error);
    }
});

而且,在这里你必须使用try / catch来捕获被拒绝的承诺。就个人而言,我没有看到这比你最初使用.then().catch()的情况要好得多,所以对于这样简单的情况(没有与其他承诺协调或序列化),它真的只是个人喜好的问题,是否.then().catch()awaittry/catch一起使用。

答案 1 :(得分:2)

您可以将async/await与调用getAllUsers的代码一起使用,而不是在getAllUsers本身使用它:

const getAllUsers = () => {
  return models.users.findAll({
      attributes: [ 'firstName', 'lastName' ]
    });
};

router.get(`${path}`, async (req, res) => {
    try {
        const users = await queries.users.getAllUsers();
        res.status(200).json(users);
    } catch (error) {
        res.status(500).send(error)
    }
});

答案 2 :(得分:0)

我发现处理此问题的最佳方法是使用中间件。

这是功能:

// based upon this
// http://madole.xyz/error-handling-in-express-with-async-await-routes/
// https://github.com/madole/async-error-catcher

export default function asyncErrorCatcher(fn) {
    if (!(fn instanceof Function)) {
        throw new Error("Must supply a function");
    }

    return (request, response, next) => {
        const promise = fn(request, response, next);
        if (!promise.catch) {
             return;
        }
        promise.catch((error) => {
            console.log(error.message);
            response.sendStatus(500);
        });

    };
}

以下是用法:

router.get("/getSettings/", asyncErrorCatcher(async (request: Request, response: Response) => {
  const settings = await database.getSettings();
  response.json(settings);
}));