【问题标题】:NodeJS mysql sync queryNodeJS mysql同步查询
【发布时间】:2023-03-28 03:34:01
【问题描述】:

我想像这样在 nodejs 中运行同步查询...

for (var i in data){

conn.query("Select 1 from user where userid="+data[i].id,function(err,row){
     Rows.push(row);
});

}

console.log(Rows);

在这段代码中,我的行一直都为空...我想运行同步查询

【问题讨论】:

    标签: javascript mysql node.js asynchronous synchronization


    【解决方案1】:

    你可能无法在线程阻塞的意义上同步使用这样的函数(你也不应该!)但如果你使用数据库连接的承诺版本(使用 Bluebird 的 promisifyAll 或特定的在 npm 上可用的 mysql 驱动程序的 promise 版本)和新的 async/await 语法(或基于生成器的协程,用于比 Node 7.x 更早的平台,其中 async/await 不可用 - 另一种选择是使用 Babel 进行转译)。

    示例 - 您可以使用这样的代码:

    for (var i in data) {
      let row = await conn.query("Select 1 from user where 
      userid="+data[i].id);
      Rows.push(row);
    }
    console.log(Rows);
    

    但如果它可以并行运行,那么这样的事情会更高效、更短:

    let Rows = await Promise.all(data.map(item =>
      conn.query("Select 1 from user where userid=" + item.id));
    console.log(Rows);
    

    有关该主题的更多详细信息,请参阅:

    注意 - 它只能在使用 async 关键字声明的函数内部使用。

    警告:您的代码可能容易受到 SQL 注入攻击。您应该在 SQL 中使用占位符而不是字符串连接。我没有修复您代码的这方面 - 有关更多详细信息,请参阅这些答案:

    【讨论】:

      【解决方案2】:

      您应该使用bluebird npm module 来解决这个问题。使用npm install bluebird安装bluebird

          var Promise = require('bluebird');
          var Rows= [];
          data.forEach(function (obj) {
             conn.query("Select 1 from user where userid="+obj.id,function(err,row){
                     Rows.push(row);
             });
            });
             return Promise.all(Rows);
          })
      

      【讨论】:

      • 这行不通。您在 forEach 回调中返回 Promise.all(Rows),该回调在每次迭代时运行一次,并忽略其返回值。此外,您正在一个不包含承诺的数组上运行Promise.all。无论如何,它应该做什么?
      【解决方案3】:

      你也可以使用异步模块。

      var async= require('async')
      async.eachSeries(arr, function(index, callback){
        conn.query("Select 1 from user where userid="+index, 
          function(err,res) {
            if (err) {
              return console.error('error running query', err);
            }else{
             Row.push(res);
            }
          callback();
      });
      },function(err){
        if(err)
         return err;
         console.log("all queries executed")
      });
      

      【讨论】:

        【解决方案4】:

        您可以制作一个返回 Promise 的包装器。使用await 可以使其同步:

        function promiseWrapper() {
            return new Promise((resolve, reject) => {
                conn.query("SQL_QUERY", queryCallback(resolve, reject);
            }
        }
        
        function queryCallback(err, row){
            return (resolve, reject) {
                resolve(row);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-11-03
          • 2018-08-12
          • 2020-10-22
          • 2020-07-08
          • 2016-03-22
          • 2017-05-23
          • 2020-06-19
          • 2017-06-06
          • 2023-03-26
          相关资源
          最近更新 更多