我应该在这个promise代码中有所收获吗?

relj7zay  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(437)

这里有一篇来自mdn的关于如何使用承诺的文章。
我清楚地检查了数据库查询中的错误,但是否也应该使用 catch 之后 then 当我使用数据库的时候?
数据库

const pool = mysql.createPool(helper.getMySQL());

const queryMaker = (query) => {
  return new Promise ((resolve, reject) => {
    pool.query(query, (error, results, fields) => {
      error ? reject(error) : resolve(results, fields);
    });
  });
};

exports.selectAllDomains = () => {
  const query = `some mysql query`;
  return queryMaker(query);
};

用例

router.route('/items').get((req, res) => {
    MySQL.selectAllDomains().then((results) => {
        if(req.user){
          results[results.length] = req.user;
        }
        res.status(200).json(results);
    });
    // Should I have a catch here?  
});
mznpcxlj

mznpcxlj1#

我应该在这个承诺代码中有一个陷阱吗?
是的,你应该。如果您的数据库调用拒绝了它的承诺,那么您就永远不会响应http请求,而http请求将只是坐在那里,没有响应被发送,最终将超时。除了无法及时向客户机发送响应之外,这还会在超时期间消耗服务器资源。如果出现一些临时数据库故障,这可能会导致大量请求堆积起来,直到它们超时,从而耗尽服务器上的资源。
相反,您需要捕获错误并立即向http请求返回错误响应。

router.route('/items').get((req, res) => {
    MySQL.selectAllDomains().then((results) => {
        if(req.user){
          results[results.length] = req.user;
        }
        res.status(200).json(results);
    }).catch(err => {
        console.log(err);
        res.status(500).send("database internal error");
    });
});

如果我猜的话,我会说不,因为我在then方法中没有做容易出错的事情。
假设db调用永远不会出错是不安全的。健壮编程预计在某些情况下可能会出现错误(磁盘错误、数据库磁盘卷脱机、连接池问题、查询错误等),并适当地处理该错误。

o2gm4chl

o2gm4chl2#

当出现db错误时,promise将返回一个错误,并且这个错误不会进入您的回调。因此,由于您正在处理一个http请求,如果出现db错误,那么客户端将不会收到响应,最终将超时。
我建议您使用catch,因为如果出现db错误,您可以使用以下命令向客户机发送正确的错误消息 res.status(500).send(error);

相关问题