【问题标题】:node js await does not seem to waitnode js await 似乎没有等待
【发布时间】:2019-06-03 07:52:12
【问题描述】:

我正在向 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);
  }
}

此代码将用于 nodejs Alexa 技能。当函数运行时,我希望日志中的输出按升序排列。我始终得到的输出是 0、1、4、2、3、3.5。 .then 部分在实际连接建立和查询数据库之前执行。

之前我尝试了一个简单的等待,而不是.then,使行

var results = await doQuery(query);

这导致完全相同的结果。我不知道为什么 await 实际上不等待。作为旁注:在块内时

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 和 Promise 的文章和文档,但我无法弄清楚这一点。

【问题讨论】:

  • 要在函数上使用await,它应该返回Promise
  • 您使用的是哪个 exact MySQL 节点库?我怀疑connection.connect 不自然地返回了一个 Promise。
  • 我正在使用 mysql/sqljs,据我所知它只使用回调,不过我可能错了。

标签: node.js asynchronous scope


【解决方案1】:

您需要将回调函数包装在Promise 中以使用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.promisifycallback包裹在promise

【讨论】:

  • 这就像一个魅力!我之前尝试了很多东西,包括util.promisify,但是它破坏了mySQL lib,所以我一定是用错了。这也解决了范围问题,因为返回了结果。你让我开心!
猜你喜欢
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
相关资源
最近更新 更多