实际上,我们将使用 async/await 语法来轻松解决这个问题。首先,让我们编写一个模型类,它将包含我们所有的 sql 查询作为类的方法。这里是:
class DB {
constructor(db) {
this.db = db;
}
async getUsers() {
let query = "SELECT * FROM users";
return this.doQuery(query)
}
async getUserById(array) {
let query = "SELECT * FROM users WHERE id = ?";
return this.doQueryParams(query, array);
}
// CORE METHODS DON'T TOUCH
async doQuery(queryToDo) {
let pro = new Promise((resolve,reject) => {
this.db.query(queryToDo, function (err, result) {
if (err) throw err;
resolve(result);
});
})
return pro.then((val) => {
return val;
})
}
async doQueryParams(queryToDo, array) {
let pro = new Promise((resolve,reject) => {
this.db.query(queryToDo, array, function (err, result) {
if (err) throw err;
resolve(result);
});
})
return pro.then((val) => {
return val;
})
}
}
module.exports = DB;
每次我们需要一个新查询时,我们都会用我们想要的查询名称编写一个新方法,并在其中包含一个字符串 var,其中包含您的 mysql 查询(提醒:当参数使用 ?需要)。然后,返回this.doQuery[Params](query) 的结果,这将是一个Promise。
注意:这里,this.doQuery() 用于我们在查询中没有任何参数时使用。如果您需要参数,请使用this.doQueryParams(),它将数组作为参数。
在您的server.js 文件中,这是如何使用它的:
let DB = require('./modelclass.js')
connection.connect(function(err) {
if (err) throw err;
let DBModel = new DB(connection);
(async function() {
let oneUser = await DBModel.getUserById([1]);
let allUsers = await DBModel.getUsers(); // we chain queries like we would do in PHP
res.render("index.ejs", {oneUser : oneUser[0], allUsers : allUsers}); // results are array, if we know there is only one row, we can use var[0] to directly send the result
})();
});
如您所见,我们正在执行 2 个查询,没有任何回调函数也没有 .then(),我们有两个包含查询结果的对象,我们可以直接将它们发送到我们的视图。您可以链接任意数量的查询。
此外,这使您无需在需要时重写每个查询,并且方法的名称应该非常明确,以使代码易于阅读。一个文件中的所有查询,其他文件中的其他内容,它更干净,你知道你的代码做什么。
常见问题:
-
返回结果是
<Promise> pending =>你确定你在调用你的方法之前输入了await吗?
-
我的查询写得很好,但我没有任何结果 => 记住这会返回 arrays,如果预期只有一行,你应该使用
var[0].property而不是var.property。