【问题标题】:Promise mysql returns undefined, how to make function wait for resultsPromise mysql返回未定义,如何让函数等待结果
【发布时间】:2018-09-18 02:17:51
【问题描述】:

我正在尝试编写一个模块,它根据传递给函数的键从 MySQL 数据库返回一个值。

以下代码在独立测试时工作正常,我能够返回结果,但是当我尝试从函数调用中获取结果时,我得到了未定义的结果。

var value = getKey("tc_api_user_key");

我怀疑这是由于返回语句。我应该如何让调用函数等待结果。

var mysql = require('promise-mysql')
    , dbConnect = require('../connection.js')
    , fs = require('fs')
    , select = fs.readFileSync(__dirname + '/queries/getallkey.sql').toString();

let getKey = (key_id) => {
mysql.createConnection(dbConnect.getConnection()).then(function(conn){
    var result = conn.query(select);
    conn.end();
    return result;
}).then(function(rows){
    // Logs out a list of hobbits
         Object.keys(rows).forEach(function(key) {
                    var item = rows[key];
                      if (key_id == item.key_id) {
                           return item.key_value;
                      }
                    });
});

}    

 var value = getKey("tc_api_user_key");
 console.log(value) 

这个问题与 conn.query() 无关,如果使用了 console.out 结果,该函数按预期工作,它只是在函数调用中不可用。可能是由于调用的异步性质。

【问题讨论】:

标签: javascript mysql node.js callback promise


【解决方案1】:

有两种方法可以做到这一点。 async 方式或promise 方式。

异步方式

let getKey = async (key_id) => {
  let conn = await mysql.createConnection(dbConnect.getConnection())
  let rows = conn.query(select);
  conn.end();
  for ([key, item] of Object.entries(rows))
  {
    if (key_id == item.key_id)
      return item.key_value;
  }
}

async function do() {
  var value = await getKey("tc_api_user_key");
  console.log(value)
}

do()

承诺方式

在此您返回一个 Promise,并在您想要返回值时在该 Promise 中解决该 Promise。

let getKey = (key_id) => {
    return new Promise( (resolve) =>
    mysql.createConnection(dbConnect.getConnection()).then(function (conn) {
        var result = conn.query(select);
        conn.end();
        return result;
    }).then(function (rows) {
        for ([key, item] of Object.entries(rows))
        {
            if (key_id == item.key_id) {
                resolve(item.key_value);
                break;
            }
        }
    })
    );
};

getKey("tc_api_user_key").then(value => {
    console.log(value)
});

当然对于错误处理,如果没有找到值,你应该拒绝承诺。但是上面的代码应该给你一个如何做的关键想法

【讨论】:

  • 对不起,这不是我要找的!!
  • 你能解释一下你不是在找什么吗?
【解决方案2】:

让我来回答我自己的问题,这要感谢一个很棒的功能“回调”,这是我通过艰难的方式学会的。

在这里,当您抽象这些模块时,最好有一个回调函数来处理来自您的调用 js 的调用,并且您可以有效地处理这些结果。

处理数据库调用的抽象模块

var mysql = require('promise-mysql')
    , dbConnect = require('../connection.js')
    , fs = require('fs')
    , select = fs.readFileSync(__dirname + '/queries/getallkey.sql').toString();


async function getKey (key_id,callback) {

try {
  callback(undefined,await dbTask(key_id)); 
}
catch(err) {
  callback(err);
}
}    

let dbTask = (key_id) => {

  return new Promise (function (resolve,reject) {
  mysql.createConnection(dbConnect.getConnection()).then(function(conn){
    var result = conn.query(select);
    conn.end();
    return result;
}).then(function(rows){
    // Logs out a list of hobbits
         Object.keys(rows).forEach(function(key) {
                    var item = rows[key];
                      if (key_id == item.key_id) {

                        resolve (item.key_value);

                      }
                    });
         });
     });

  }

调用模块

let getTeamcityServer = (serverUrl, callback) => {

  try {

    selectKey.getKey("tc_api_user_key",(errorMessage, api_pass) => {

      if (errorMessage) {
        callback(errorMessage);
      }
      else {

          auth = vault.decrypt(api_pass);
          callback(undefined,teamcity.create({
          url: serverUrl,
          username: "XXXXXXXX",
          password: auth

          }));

      }

    });

  }
  catch(err) {

    callback(err);


  }



}

【讨论】:

  • 所以你把 Async、await、Promise、callbacks 混合在一个好汤里
  • 是的,因为没有人能提出更好的方法
  • 这是一个糟糕的答案,最糟糕的是它混合了模式并包含了诸如 async 之类的东西而没有 await 然后继续使用回调。看起来您试图避免将赏金交给显然更好的答案,展示下面的 es6 的最佳实践。请删除您的低质量答案。
  • @lix 我希望串行投票脚本在 03:00 UTC 将其反转。如果不是这种情况,请标记您的帖子以引起版主注意并解释发生了什么。
  • 我将赏金授予正确答案的人。谢谢。
猜你喜欢
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 2020-10-03
  • 2021-07-17
  • 1970-01-01
  • 2021-07-24
  • 2021-06-03
相关资源
最近更新 更多