Сохраняйте строки запроса mysql в переменной для последующего использования

Я делаю проект системы мониторинга, в котором данные датчиков Arduino отправляются на сервер node.js (через запросы GET), а затем сохраняются в базе данных MySQL.

Всякий раз, когда я успешно отправляю данные на сервер, он подключается к базе данных MySQL и запрашивает последние 5 полученных записей, чтобы выполнить некоторую обработку.

Поэтому мне нужно сохранить строки этих 5 записей в переменной для последующего использования. Это означает, что я должен получить строки из connection.query в переменной.

Я читал, что тот факт, что я не могу этого сделать, связан с тем, что node.js является асинхронным. Итак, мои вопросы:

  1. Можно ли выполнить описанные задачи так, как я пытаюсь?
  2. Если нет, то есть ли другой способ сделать это?

Я не помещаю сюда весь код, но запускаю отдельный тест, который также работает неправильно. Вот:

var mysql = require('mysql');

var con = mysql.createConnection({
      host    : "127.0.0.1",
      user    : "root",
      password: "xxxx",
      database: "mydb",
      port    : 3306
});
var queryString = "SELECT id, temp1, temp2, temp3, temp4, level_ice_bank, flow FROM tempdata ORDER BY id DESC LIMIT 5";

con.connect(function(err) {
  if (err) throw err;
});

var result_arr = [];
function setValue (value) {
  result_arr = value;
}

con.query(queryString, function (err, rows, fields) {
  if (err) throw err;
  else {
    //console.log(rows);
    setValue(rows);
  }
});

console.log(result_arr);

Он регистрирует:

[]

Но если я раскомментирую console.log(rows);, он запишет то, что мне нужно сохранить в переменной result_arr.

Заранее всем спасибо.


person arocha    schedule 06.07.2017    source источник
comment
Поток не будет ждать завершения con.query. Он немедленно выполнит console.log(result_arr) после выполнения строки con.query, поэтому значение не регистрируется, потому что con.query еще не завершил запрос. У вас есть результат, когда вы раскомментируете //console.log(rows); потому что con.query завершил выполнение. Рассматривайте это так, как будто выполняется con.query, создается новый поток для запуска его выполнения, а основной поток продолжает свою жизнь, даже если con.query еще не завершен.   -  person suguspnk    schedule 06.07.2017
comment
@suguspnk спасибо за объяснение! Я более или менее понял, что должно быть что-то в этом роде. Вы знаете, как сделать так, чтобы setValues(rows); произошло раньше console.log(result_arr);?   -  person arocha    schedule 06.07.2017
comment
Смотрите ответ Дэна. Это правильный подход к этому.   -  person suguspnk    schedule 06.07.2017


Ответы (1)


Вы видите такое поведение, потому что con.query(...) — асинхронная функция. Что означает, что:

console.log(result_arr);

Работает до:

con.query(queryString, function (err, rows, fields) {
  if (err) throw err;
  else {
    //console.log(rows);
    setValue(rows);
  }
});

(В частности, вызов setValue(rows))

Чтобы исправить это в вашем примере, вы можете просто сделать:

con.query(queryString, function (err, rows, fields) {
  if (err) throw err;
  else {
    setValue(rows);
    console.log(result_arr);
  }
});

Если вы хотите сделать больше, чем просто регистрировать данные, вы можете вызвать функцию, которая зависит от result_arr из обратного вызова con.query, например:

con.query(queryString, function (err, rows, fields) {
  if (err) throw err;
  else {
    setValue(rows);
    doCleverStuffWithData();
  }
});

function doCleverStuffWithData() {
    // Do something with result_arr
}
person dan    schedule 06.07.2017
comment
Также стоит упомянуть, что функциональность async/await может быть добавлена ​​в модуль Node.js mysql с помощью немного работы. Это также решит вашу проблему. Надеемся, что поддержка этого будет добавлена ​​в пакет mysql в будущем. - person dan; 06.07.2017
comment
ваше объяснение было идеальным, оно сработало так, как я хотел, и я думаю, что теперь я могу продолжить работу над проектом. Спасибо! - person arocha; 06.07.2017
comment
@AntónioRocha Отлично, я очень рад, что это помогло. Концепция асинхронного/обратного вызова в JavaScript определенно стоит того, чтобы о ней поразмыслить на раннем этапе :) - person dan; 06.07.2017
comment
@dan Я пытаюсь вернуть result_arr в функцию doCleverStuffWithData(), но все равно получаю сообщение Promise Pending. Любые идеи? - person fpolig01; 19.12.2018