Promise mysql返回未定义,如何让函数等待结果

Posted

技术标签:

【中文标题】Promise mysql返回未定义,如何让函数等待结果【英文标题】:Promise mysql returns undefined, how to make function wait for results 【发布时间】: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 结果,该函数按预期工作,它只是在函数调用中不可用。可能是由于调用的异步性质。

【问题讨论】:

How do I return the response from an asynchronous call?的可能重复 您的conn.query() 调用是异步的。您需要向它传递一个回调并在其中处理响应。 【参考方案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 将其反转。如果不是这种情况,请标记您的帖子以引起版主注意并解释发生了什么。 我将赏金授予正确答案的人。谢谢。

以上是关于Promise mysql返回未定义,如何让函数等待结果的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云函数 - 返回未定义、预期的 Promise 或值

Firebase 云函数错误:函数返回未定义、预期的 Promise 或值

函数以状态完成:'ok',但控制台日志显示函数返回未定义、预期的 Promise 或值

函数返回未定义、预期的 Promise 或值 Firebase 日志错误

函数返回未定义,预期Promise或值和通知长时间延迟

Cloud Functions 错误:函数返回未定义、预期的 Promise 或值,以及 TypeError:无法读取未定义的属性“First_Name”