【问题标题】:Return value from MySQL with Node.js使用 Node.js 从 MySQL 返回值
【发布时间】:2020-05-22 14:30:48
【问题描述】:

如果您曾经尝试使用 Node.js 从 MySQL 获取返回值,您应该会发现它很复杂,有很多未定义的结果。

当我们在 Internet 上寻找答案时,似乎只有一种方法可以“正确”地使用 MySQL 返回结果,并且代码可读:Promises。

但是,即使是 Promise 也可以使用 .then() 链接,最后,它与我们通常用于 mysql 和节点的回调函数并没有太大变化。

那么,有没有一种优雅的方式来链接结果,就像我们使用 PHP 所做的那样?

是的。


【问题讨论】:

  • 这种类型的问题似乎高度依赖于您使用的节点库,您没有提到,其次,您似乎对 Javascript 的异步性质和如何使用async/await。从 SQL 查询中获取值我真的没有问题,因为我知道如何与我的库返回的 Promise 进行交互
  • 我认为,您的方法众所周知,可以在 Google 中轻松找到。只是说!
  • @TKoL 是的,我不知道 promises 和 async 是如何工作的,我只是在这种情况下使用它。如果您确实喜欢一个页面的 5/6 查询,或者如果您需要对另一个查询使用查询,这不是解决问题,而是优雅的方式。
  • @Ele 我只找到了一个直接通过await db.query() 解释的主题,但我从来没有让它工作:/

标签: javascript mysql node.js


【解决方案1】:

实际上,我们将使用 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

【讨论】:

  • 当然,它需要 try/catch 来改进它,但我不知道在哪里可以做到
猜你喜欢
  • 2016-08-01
  • 2014-09-27
  • 2020-08-21
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
相关资源
最近更新 更多