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 日志错误
Cloud Functions 错误:函数返回未定义、预期的 Promise 或值,以及 TypeError:无法读取未定义的属性“First_Name”