Nodejs mysql асинхронный вызов (ожидание завершения запроса к БД) - PullRequest
0 голосов
/ 23 февраля 2020

У меня проблема, я хочу, чтобы мой код выполнил запрос к базе данных, а затем перешел к следующим командам, как мне это сделать, единственное решение, которое я нашел, - это обещание, asyn c и ожидание. Я не мог найти способ объединить их. Пожалуйста, используйте этот код и покажите мне необходимые изменения и где я должен их включить.

Код выглядит следующим образом:

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

Я просто хочу, чтобы код дождался завершения запроса к БД и затем перешел к следующему шагу, чтобы я мог в будущем соответствующим образом манипулировать результатами запроса к БД.

Заранее спасибо

1 Ответ

0 голосов
/ 23 февраля 2020

Метод запроса является асинхронным, поэтому вы не можете ожидать, что поток будет ожидать его завершения.

Самый базовый c подход заключается в том, чтобы следовать вашему потоку внутри обратного вызова

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}");
       });
    });
});

Если вы переключитесь на подход, основанный на обещаниях, вы можете инкапсулировать каждый вызов в connection.query для возврата обещание, такое как:

  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;
    });

Или, используя async / await

  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;
  });

Уже есть библиотека, которая делает выше для вас

В любом случае, уже есть библиотека-оболочка обещание - mysql, которая выполняет работу по упаковке обещаний:

# Promise approach
const mysql = require('promise-mysql');

mysql
    .createConnection({...})
    .then(connection => {
      return connection.query(sentence1);
    })
    .then(results1=>{...})
    .catch(err=>{...});

или
# Асинхронный / ожидающий подход const mysql = require ('обещание 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

Sidenote

Кстати: вам не нужно начинать с Promise.resolve(), чтобы обернуть все в асинхронную функцию c. Я просто думаю, что

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

легче понять, чем

(async () => {
    …
})().catch(err => {
    console.error(err);
});
...