узел js await похоже не ждет - PullRequest
0 голосов
/ 08 января 2019

Я делаю запрос к базе данных mySQL и хочу работать с возвращенными результатами. У меня есть асинхронная функция

async function doQuery(query) {
  try {
    console.log('0. connection start');
    var connection = MySQL.createConnection({  
      host: "xxxxxxxx",
      user: "yyyyyyyy",
      password: "zzzzzzzz"
    });

    console.log('1. Connection set up. Connecting...');
    var queryResults;
    await connection.connect(function(err) {
      if (err) console.log(err);
      console.log("2. Connected!");
      connection.query(query, function(err, result) {
        if (err) console.log(err);
        queryResults = JSON.parse(JSON.stringify(result));
        console.log("3. " + util.inspect(result, {depth: 4}));
        console.log("3.5 " + util.inspect(queryResults, {depth: 4}));
        connection.end();
      });
    })

    console.log ("results before return:" + JSON.stringify(queryResults));
    return queryResults;
  }
  catch (err){
    console.log("async err: " + err);
  }
}

Затем функция вызывается из другой функции:

function handle async(handlerInput) {
  console.log("ExecuteDBSearchHandler");

  var query = buildQuery(handlerInput);
  try{
    var resultsPromise = doQuery(query)
      .then(results => {
        console.log("4. final results: " + results);
        const count = results.length;
        var speechText = 'Abfrage Erfolgreich, es gab ' + count + " Ergebnisse.";
        return handlerInput.responseBuilder
          .speak(speechText)
          .withSimpleCard('Abfrage Erfolgreich', speechText)
          .withShouldEndSession(false)
          .getResponse();
      })
  }
  catch (err){
    console.log("error:" + err);
  }
}

Этот код используется в навыке Alexa узла nodejs. Когда функция запустится, я ожидаю, что выходы в журнале будут упорядочены по возрастанию. Выходные данные, которые я последовательно получаю, составляют 0, 1, 4, 2, 3, 3,5. Часть .then выполняется до установления фактического соединения и запроса к базе данных.

Вместо .then я пробовал простое ожидание раньше, делая строку

var results = await doQuery(query);

Это привело к точно такому же результату. Я в недоумении относительно того, почему ожидают, а не ждать. В качестве обозначения: Находясь внутри блока

connection.query(query, function (err, result) {
  if (err) console.log(err);
  queryResults = JSON.parse(JSON.stringify(result));
  console.log("3. " + util.inspect(result, {depth: 4}));
  console.log("3.5 " + util.inspect(queryResults, {depth: 4}));
  connection.end();
});

queryResults показывает результаты (в шаге 3.5 журнала отладки). В строке

console.log ("results before return:" + JSON.stringify(queryResults));  

возвращает неопределенное значение. Я пробовал так много вещей, чтобы получить результаты в области функций doQuery, но я не могу этого достичь. Неужели ожидание терпит неудачу из-за этого? И как я могу это исправить? Я прочитал более десятка статей и документов об async / await и обещаниях, но я не могу понять это.

1 Ответ

0 голосов
/ 08 января 2019

Вам нужно обернуть свою функцию обратного вызова в Обещание , чтобы использовать await ключевое слово

Например:

async function dbQuery(query) {
    try {
        const connection = MySQL.createConnection({  
            host: "xxxxxxxx",
            user: "yyyyyyyy",
            password: "zzzzzzzz"
        });

        return new Promise(function(resolve, reject) {
            connection.connect(function(err) {
                if (err) reject(err);

                connection.query(query, function (err, result) {
                    if (err) reject(err);
                    connection.end();
                    resolve(JSON.parse(JSON.stringify(result)));
                });
            });
        });
    } catch {
        console.error("async err: " + err);
    }
}

Также можно использовать util.promisify , чтобы обернуть callback в promise

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...