我在节点中遇到了promises的问题,特别是在下面的代码中,我编写了这些代码来执行MySQL查询,所以我所有的其他100多个函数都可以共享它而不是内联编写它。来自PHP开发,了解promises和whatnot的好处是一个学习曲线,现在我遇到了一些问题。以下是将query
作为参数,执行并返回响应的函数:
var mysql = require('mysql');
const myDBConnection = mysql.createPool({
host: '127.0.0.1',
user: "username",
password: "password",
database: "dbName",
connectionLimit: 101,
});
class DBQueryRunner {
query(query) {
return new Promise((resolve, reject) => {
myDBConnection.getConnection((err, connection) => {
const myQuery = mysql.format(query.string, query.params);
connection.query(myQuery, function(err, data) {
return (err ? reject(err) : resolve(data));
connection.release();
});
});
});
}
}
代码运行正常并且值返回给调用者,但它似乎没有终止,无论我尝试什么,我担心它正在占用CPU资源。
这是一个示例函数,您可以在命令行中使用上述函数来查看正在发生的事情。
function test() {
let DBQueryRunner = require("./theAboveCode.js");
const myDB = new DBQueryRunner();
let query = {
string: `SELECT 1+1 AS Output`,
params: []
};
return myDB.query(query).then(rows => {
console.log(rows)
return (rows);
});
}
问题:
- 承诺是否有必要终止?
- 我的代码中有错误吗?
- 有没有更好的方法来制作像我一样的可重用数据库执行功能?
UPDATE - 我还尝试了一种使用Bluebird来“宣传”mysql库的替代方法。该功能仍然永远不会结束,我必须在我的终端中按CTRL + C才能退出它。
let mysql = require('mysql');
let Promise = require('bluebird');
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
let myDBConnection = mysql.createPool({
host: '127.0.0.1',
user: "username",
password: "password",
myDBConnection: "dbName",
connectionLimit: 101,
});
class DBQueryRunner {
query(query) {
let pool = Promise.promisifyAll(mysql);
return myDBConnection.getConnectionAsync()
.then(function (conn) {
myDBConnection = Promise.promisifyAll(conn);
return myDBConnection.queryAsync(query.string, query.params);
})
.then(function (results) {
if (results.length < 1) {
return "No results were found";
} else {
return results;
// resolve(results); //This method doesn't work with resolve/reject so I already am confused by it.
}
})
.catch(function (err) {
console.log(err);
throw err;
})
.finally(function () {
if (myDBConnection) {
myDBConnection.release();
console.log("Released the connection")
}
});
}
}
答案 0 :(得分:2)
我找到了解决问题的解决方案。
使用connection.destroy()
可以让函数正常结束,因此它们不再导致&#34;挂起&#34;。
我在原帖中发布的两组代码可以正常运行,因此将来可能对其他人有所帮助。
答案 1 :(得分:0)
你应该调用resolve('返回一些数据');当所有操作和你释放mysql描述符时。尝试将其更改为
connection.release();
return (err ? reject(err) : resolve(data)); // The return operator will EXIT from function before connection released. Maybe this is what causes the problem
承诺是否有必要终止?
承诺不会终止。 Promise有三种状态:Running,Rejected,Resolved。因此,如果您的先前承诺仍在执行,则不会调用.then()链。所以,是的,您必须为您的承诺设置适当的状态:已解决或拒绝,以便调用下一个链式操作。
我的代码中有错误吗?
是的,你定义错误地使用return语句。请注意,只要您调用返回,您的功能就会终止,并且返回语句后的代码将无法执行