我正在使用 node.js 和 express,还有 mysql。我使用连接池来请求连接并在其上创建承诺,以限制回调噩梦,以下代码段设置在我稍后导入的文件中,请注意,我设置了一个处理程序,error
以便在出现任何情况时不终止应用程序真的错了
exports.getConnection = () => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
reject(`Could not obtain the connection from the pool: ${err}`);
}
connection.on('error', err => {
console.log(`SQL error (code: ${err.code}, message: ${err.sqlMessage}) while executing query: ${err.sql}`);
});
resolve(connection);
});
});
};
这是用例的示例(想法是获取连接,将查询链接到 中then
,如果发生非致命错误,我将抛出它并在catch
处理程序中处理连接释放
// Exception handler that release the connection then call the callback
function releaseConnectionHandler(err, connection, callback) {
connection.release();
callback(err, null);
}
exports.someRequest = function(ID, callback) {
sqlPool.getConnection().then(connection => {
connection.query("SELECT * from tableNotExists",
(err, result) => {
if (err) {
throw ({ err, connection, callback });
}
connection.release();
callback(null, result);
});
}).catch(({ err, connection, callback}) => releaseConnectionHandler(err, connection, callback));
};
查询将失败,但我看到处理程序甚至没有被调用(我在其中添加了一些跟踪......)并且应用程序终止于
node_modules/mysql/lib/protocol/Parser.js:80
throw err; // Rethrow non-MySQL errors
正确的查询不会有任何麻烦...任何想法我在错误处理上做错了什么?
您正在重新抛出传递给查询回调的错误,您正在使用的库也会重新抛出该错误,最终没有在任何地方正确捕获和处理并导致失败。你不在 Promise 的上下文中throw
,而是在从mysql
模块调用的回调函数的上下文中。
您还不必要地混合了 Promise 和回调,尤其是您要导出的函数。您的问题表明您想摆脱回调,所以我将根据该指示来回答这个问题。
要解决主要问题,请不要抛出错误。相反,将它传递给被调用者:
const promisify = require("util").promisify;
exports.someRequest = function (ID) {
return sqlPool.getConnection().then(connection => {
return promisify(connection.query)("select * from tableNotExist")
.finally(connection.release);
});
};
连接将始终释放回池,无论是成功还是错误。然后,您可以使用以下方法调用该方法:
yourModule.someRequest(id).then((results) => {
// Do something with the result set
}).catch((e) => {
// Handle error. Can be either a pool connection error or a query error.
});
如果您有可能使用async/await
,则可以重写代码:
const promisify = require("util").promisify;
exports.someRequest = async function (ID) {
let connection = await sqlPool.getConnection();
try {
return await promisify(connection.query)("select * from tableNotExist");
} finally {
connection.release();
}
};
我还建议使用,node-mysql2
因为除了回调样式的 API 之外,它们还有基于 Promise 的 API,而且在我的经验中也有更好的性能。然后,您不必编写这些乏味的包装器,而只需准备require('mysql2/promise')
好即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句