【问题标题】:Nodejs mysql asynchronous calling (waiting for the DB query to be over)Nodejs mysql异步调用(等待DB查询结束)
【发布时间】:2020-06-07 08:32:12
【问题描述】:

我有一个问题,我希望我的代码完成数据库查询,然后继续执行下一个命令,我该如何实现它,我找到的唯一解决方案是使用 promise、async 和 await。我找不到任何方法来整合它们。请使用此代码并向我展示必要的更改以及我应该将它们合并到哪里。

代码如下:

const mysql = require('mysql')
const bodyparser = require('body-parser');

console.log("in the db1")

  let gh="select * from table1"
  var connection = mysql.createConnection({
  host: 'xxxxxxxxxx',
  user: 'root',
  password: 'root',
  database: 'db1'
  })

  connection.query(gh, function (error, results, fields) {
    console.log('Connection Successful')
    connection.end();
  })
console.log("in the db2")

我得到的输出是:

in the db1
in the db2
Connection Successful

我只希望代码等待数据库查询完成,然后继续下一步,以便我以后可以相应地操作数据库查询结果。

提前致谢

【问题讨论】:

    标签: mysql node.js asynchronous async-await


    【解决方案1】:

    查询方法是异步的,因此您不能期望流程等待它结束。

    最基本的方法是在回调中遵循您的流程

    console.log("before query1");
    
    connection.query(query1, function (error, results, fields) {
        console.log("after query1");
    });
    

    但是,如果您想进行子查询,这可能会导致回调噩梦:

    connection.query(query1, function (error, results, fields) {
        console.log("after query1", {results,fields});
    
        connection.query(query2, function (error2, results2, fields2) {
           console.log("after query2", {results2,fields2});
    
           connection.query(query3, function (error3, results3, fields3) {
              console.log("after query3, {results3,fields3}");
           });
        });
    });
    

    如果您切换到基于 Promise 的方法,您可以封装对 connection.query 的每个调用以返回一个 Promise,例如:

      const mysql = require('mysql-promise'),
        connection = mysql.createConnection({...});
    
      connection.connect();
    
      async function queryAsync(sentence) {
        return new Promise((resolve, reject) => {
          connection.query(sentence, function(error, results, fields) {
            if (error) {
              reject(error);
            }
            resolve( results);
          });
        });
      }
    

    然后:

      Promise.resolve()
        .then(() => {
          return queryAsync(sentence1);
        })
        .then(results1 => {
          console.log('after query 1',  results1);
          return queryAsync(sentence2);
        })
        .then(results2 => {
          console.log('after query 2',  results2);
          return queryAsync(sentence3);
        })
        .then(results3 => {
          console.log('after query 3',  results3);
          connection.end();
          return;
        })
        .catch(err => {
          console.error(err);
          connection.end();
          return;
        });
    

    或者,使用异步/等待

      Promise.resolve().then(async () => {
        try {
          let  results1 = await queryAsync(sentence1);
          console.log('after query1',  results1);
    
          let  results2 = await queryAsync(sentence2);
          console.log('after query2',  results2);
    
          let  results3 = await queryAsync(sentence3);
          console.log('after query3',  results3);
        } catch (err) {
          console.error(err);
        }
        connection.end();
    
        return;
      });
    

    已经有一个库可以为您完成上述工作

    无论如何,已经有一个包装库 promise-mysql 为您完成承诺包装工作:

    # Promise approach
    const mysql = require('promise-mysql');
    
    mysql
        .createConnection({...})
        .then(connection => {
          return connection.query(sentence1);
        })
        .then(results1=>{...})
        .catch(err=>{...});
    

    或者
    # 异步/等待方法 const mysql = require('promise-mysql');

     mysql
        .createConnection({...})
        .then(async connection => {
          try {
          let  results1 = await connection.query(sentence1);
          console.log('after query1',  results1);
          ...
          } catch (err) {
            console.error(err);
          }
          return connection.end();
      });
    

    试试 RunKit

    旁注

    顺便说一句:您无需以 Promise.resolve() 开头即可将所有内容包装在异步函数中。我只是觉得

    Promise.resolve()
      .then(()=> {
         …
      }).catch(err => {
        console.error(err);
      });
    

    更容易理解
    (async () => {
        …
    })().catch(err => {
        console.error(err);
    });
    

    【讨论】:

    • 我尝试了上面列出的所有方法,但都没有奏效,请你用工作代码澄清一下,或者你能不能修改我提到的代码,因为我仍然尝试了 db 下面的命令正在执行并且没有等待完成数据库查询。
    • 我的问题是我需要对数据库查询的结果进行回调。回调仍然在上面的代码中执行,变量的未定义值作为数据库查询。我希望回调在执行查询后返回一个值(该值是名字)
    • 如果你没有将回调传递给查询方法,而是await它,var results = await db.query(/*.. no callback../*) 它将被存储在变量results 中。在下一行你可以打电话给cb(null, results)
    猜你喜欢
    • 2020-06-19
    • 2019-05-25
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    相关资源
    最近更新 更多