【问题标题】:Node.js express and mySQL dataNode.js express 和 mySQL 数据
【发布时间】:2018-08-09 18:09:41
【问题描述】:

我刚开始学习 JavaScript 和 Node.JS,我真的很纠结回调的概念。所以我继续尝试实现它们以将 mySQL 数据推送到站点。

我是这样开始的:

// connection stuff happened already. Connection works fine.

app.get('/home', function(req,res){

var sql = `select u.* from users u`;

var sql2 = `select u.* from users2 u`;

usersA = [];
usersB = [];
connection.query(sql, function(error, results, fields){
    if (error) throw error;
    results.forEach(function(user){
        usersA.push({
            "id":user.id,
            "name":user.name,
            "lastname":user.lastname
        });
    });
    connection.query(sql2, function(error, results, fields){
      if (error) throw error;
      results.forEach(function(user){
        usersB.push({
            "id":user.id,
            "name":user.name,
            "lastname":user.lastname
        });
      });
      res.render("index", {
        usersA: usersA,
        usersB: usersB
      });
    });
  });
});

这行得通。但考虑到可能有超过 2 个查询,我觉得这是错误的方法。

我需要在渲染索引之前填充两个数组。而且我希望在不相互嵌套多个查询的情况下更直接地实现这一点。

也许我只是不习惯这样的代码。如果即使对于 10 个或更多查询,这也是一种有效的方法,我会坚持使用它。就是感觉不对。

所以我开始研究 this SO thread 并试图以某种方式让事情发挥作用,但它没有:

function executeQuery(query, callback) {
  connection.query(query, function (err, rows, fields) {
    if (err) {
      return callback(err, null);
    } else {
      return callback(null, rows);
    }
  })
}

function getResult(query,callback) {
  executeQuery(query, function (err, rows) {
    if (!err) {
      callback(null,rows);
    } else {
      callback(true,err);
    }
  });
}

function getUsers(sqlQry){
  getResult(sqlQry,function(err,rows){
    if(!err){
      return rows;
    } else {
      console.log(err);
    }
  });
}

准备好之后,我尝试了以下方法:

var sql = `select u.* from users u`;
var sql2 = `select u.* from users2 u`;

app.get('/home', function(req,res){
  res.render("index", {
    usersA: getUsers(sql),
    usersB: getUsers(sql2)
  });
}

但是我的 usersA/usersB 是空的。我猜这是某种范围/异步问题,因为 getUsers() 在执行查询之前返回。

根据我目前所读到的内容,这可能是一个承诺的好地方。

我在我的解决方案中添加了答案。

【问题讨论】:

  • 你能说明你是如何嵌套那些不起作用的吗?
  • 您是否尝试在第一个回调中进行第二个查询?看起来你甚至没有尝试过。
  • 查看 node.js promises。您可以使用 Promise 将回调链接在一起,然后在所有回调完成后,您可以执行任何您想要的操作。
  • 明天我会添加我的尝试。我肯定尝试过不同的方法。
  • 我添加了我的方法,说明什么有效,什么无效。

标签: mysql node.js


【解决方案1】:

我找到了问题的答案

我在 codeburst 上找到了this article 关于 Node.js 和 mySQL 使用 Promise 的信息,并尝试了它。所以这一切都归功于他们。

app.get('/home', function(req,res){
  var db = new Database({
    host     : "someHost.someDomain",
    user     : "someUser",
    password : "somePassword",
    database : "someDatabase"
  });

var sql = `select u.* from users u`;
var sql2 = `select u.* from users2 u`;

usersA = [];
usersB = [];

db.query(sql)
    .then(rows => {
                rows.forEach(function(user){
                    usersA.push({
                        "id":user.id,
                        "name":user.name,
                        "lastname":user.lastname
                    });
                });
            return db.query(sql2)
        })
    .then(rows => {
                rows.forEach(function(user){
                    usersB.push({
                        "id":user.id,
                        "name":user.name,
                        "lastname":user.lastname
                    });
                });
                return db.close();
        }, err => {
    return db.close().then( () => { throw err; } )
    })
    .then( () => {
        res.render("index", {
            usersA: usersA,
            usersB: usersB
        });
    }).catch( err => {
        console.log(err);   
} )

我还没有真的了解它是如何工作的,但我会阅读它。这允许使用 Promise 处理多个 嵌套 查询,这比简单地嵌套所有内容更容易处理。

如果有人有其他方法或觉得有必要解释这里发生的事情,我会非常感激!

为了在不访问 URL 的情况下完成,这里是提到的数据库类:

class Database {
  constructor( config ) {
    this.connection = mysql.createConnection( config );
  }
  query( sql, args ) {
    return new Promise( ( resolve, reject ) => {
        this.connection.query( sql, args, ( err, rows ) => {
            if ( err )
                return reject( err );
            resolve( rows );
        } );
    } );
  }
  close() {
    return new Promise( ( resolve, reject ) => {
        this.connection.end( err => {
            if ( err )
                return reject( err );
            resolve();
        } );
    } );
  }
}

【讨论】:

    猜你喜欢
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 2014-07-21
    相关资源
    最近更新 更多