Javascript 我应该在这个承诺代码中有一个陷阱吗?
人们读到这篇文章是关于如何使用承诺的 我清楚地检查了数据库查询中的错误,但在使用数据库时是否也应该在Javascript 我应该在这个承诺代码中有一个陷阱吗?,javascript,mysql,node.js,es6-promise,Javascript,Mysql,Node.js,Es6 Promise,人们读到这篇文章是关于如何使用承诺的 我清楚地检查了数据库查询中的错误,但在使用数据库时是否也应该在之后使用catch,然后使用 数据库 const pool = mysql.createPool(helper.getMySQL()); const queryMaker = (query) => { return new Promise ((resolve, reject) => { pool.query(query, (error, results, fields)
之后使用catch
,然后使用
数据库
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?
});
用例
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?
});
当出现DB错误时,promise将返回一个错误,并且该错误不会进入您所拥有的then回调。因此,由于您正在处理一个HTTP请求,如果出现DB错误,那么客户端将不会收到响应,最终将超时
我建议您使用catch,因为如果出现DB错误,您可以向客户端发送一条正确的错误消息,例如res.status(500).send(error)代码>
我应该在这个承诺代码中有一个陷阱吗
是的,你应该。如果您的数据库调用拒绝了它的承诺,那么您将永远不会响应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调用永远不会出错是不安全的。健壮的编程预计在某些情况下可能会出现错误(磁盘错误、数据库磁盘卷脱机、连接池问题、查询错误等),并适当地处理该错误。如果MySQL出现问题。selectAllDomains()
,则您将无法捕获该错误,节点将崩溃(在将来的某些版本中),现在您只会收到一个未经处理的拒绝警告。此行不应该处理它吗?error?reject(error):resolve(results,fields);
Well..当您调用reject(error)时你没有处理它。你只是在传播错误。我发现我必须在调用它的应用程序文件中为我的数据库添加错误处理代码,这很烦人。我没有办法解决这个问题。不一定。你也可以在DB文件中处理它。你有return queryMaker(query)
您可以在那里添加catch语句。您也不必调用reject。如果出现错误,您可以使用空承诺或其他方式解决。假设采用快速路由,则可以通过使用next()
继承默认错误处理来进一步简化catch语句,例如.catch(next)
@Johnmorsey-这是否回答了您的问题?如果回答了,请通过单击答案左侧的复选标记向社区表明这一点。这也将为您在此处遵循正确的程序赢得一些声誉点数。如果回答不正确,请指出尚未回答的问题。