从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值
Posted
技术标签:
【中文标题】从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值【英文标题】:How to get return values from Async/await function when fetching the data from mySQL in Nodejs 【发布时间】:2019-10-17 18:26:38 【问题描述】:我正在从 DB 中获取一些交换数据,然后提取不同交换的名称并再次传递给 mysql 查询以从不同的表中获取数据。
我面临的问题是异步等待不返回值,而只是返回 Promise 。
下面是我正在尝试的代码,想知道我哪里出错了。
//Function that fetches the exchanges from DB
const getExchange = () =>
return new Promise((resolve, reject) =>
db.connection.query(`
SELECT *
FROM,
(
SELECT
exchange,
COUNT(pair) as noOfMarkets
FROM ticker_data
) as t
`, (err, resp) =>
if (!err)
resolve(resp)
else
reject(err)
)
)
// push unique exchanges to an array.
const getExchangesData = async () =>
const allExchanges = await getExchanges();
let exchanges = []
allExchanges.forEach(item =>
let exchange =
exchange: item.exchange
exchanges.push(exchange)
)
return await exchanges
// mapping through an array of exchanges and passing to DB query to get data from the DB.
const getSingleExchange = async () =>
const exchanges = await getExchangesData()
await Promise.all(exchanges.map(async (item) =>
db.connection.query(`
SELECT
exchange_rank,
name
volume24hUSD
(
SELECT
volume24hUSD as tradingVolYesterday
FROM exchanges
WHERE name = '$item.exchange'
AND createdAt >= now() -interval 1 day
AND createdAt < now() -interval 1 day + interval 120 second
LIMIT 1
) volumeDay1
FROM exchanges
WHERE name = '$item.exchange'
`, (err, resp) =>
if (!err)
console.log(resp) // getting all the values
let volData =
name: resp[0].name,
exchange_rank: resp[0].exchange_rank,
icon: resp[0].icon
return volData
)
))
const data = getSingleExchange()
console.log(data) // returning Promise <pending>
编辑
在回答中建议进行更改后,我仍然有一个问题:
//Function that fetches the exchanges from DB
const getExchange = () =>
return new Promise((resolve, reject) =>
db.connection.query(`
SELECT *
FROM,
(
SELECT
exchange,
COUNT(pair) as noOfMarkets
FROM ticker_data
) as t
`, (err, resp) =>
if (!err)
resolve(resp)
else
reject(err)
)
)
// push unique exchanges to an array.
const getExchangesData = async () =>
const allExchanges = await getExchanges();
let exchanges = []
allExchanges.forEach(item =>
let exchange =
exchange: item.exchange
exchanges.push(exchange)
)
return await exchanges
// mapping through an array of exchanges and passing to DB query to get data from the DB.
const getSingleExchange = async () =>
const exchanges = await getExchangesData()
await Promise.all(exchanges.map((item) =>
return new Promise((resolve, reject) =>
db.connection.query(`...`, (err, resp) =>
if (!err)
resolve(resp)
else
reject(err)
).then(resp =>
console.log(resp)
let volData =
name: resp[0].name,
exchange_rank: resp[0].exchange_rank,
icon: resp[0].icon
return volData
)
)
))
getSingleExchange().then(data =>
console.log(data)
);
我现在收到此错误:
(node:30583) UnhandledPromiseRejectionWarning: TypeError:
db.connection.query(...).then
不是函数 在承诺 (/getExchanges.js:217:16) 在新的 Promise () 在 Promise.all.exchanges.map (/getExchanges.js:145:16) 在 Array.map() 在 getSingleExchange (/getExchanges.js:144:33)
【问题讨论】:
【参考方案1】:主要问题在这部分:
await Promise.all(exchanges.map(async (item) =>
那个map
回调没有返回任何东西,它没有await
,所以使用async
没有意义。
改为删除async
:
await Promise.all(exchanges.map((item) =>
...并在回调函数中返回一个承诺,就像您在第一个函数中所做的那样:
return new Promise((resolve, reject) =>
db.connection.query(`...`), (err, resp) =>
if (!err)
resolve(resp)
else
reject(err)
)
).then(resp =>
console.log(resp)
let volData =
name: resp[0].name,
exchange_rank: resp[0].exchange_rank,
icon: resp[0].icon
return volData
);
您将从编写一个承诺query
的通用函数中受益,这样您就不必为您需要的每个查询都执行new Promise
的事情。
最后,你不能指望同步获得异步结果:async
函数不会同步返回异步结果,而是为它返回一个 Promise。所以你的最后几行(主要代码)应该还在等待。所以要么这样做:
(async () =>
const data = await getSingleExchange()
console.log(data)
)(); // immediately executing (async) function expression
或者:
getSingleExchange().then(data =>
console.log(data)
);
注意:在第二个函数中执行 return await exchanges
毫无意义(exchanges
不是承诺),因此您可以执行 return exchanges
。
【讨论】:
感谢回复,得到相同的回复 Promise.query(....).then
,正如错误消息中所说的那样?这不在我的回答中。也请不要这样调整您的问题。这让我的回答看起来无关紧要。如果您想为您的问题添加信息,那没关系,但请保留原始问题。注意:您在问题中添加的新代码是 not 就像我在回答中所说的那样。 then
放错地方了。
我修复了这一行中的错误 db.connection.query(...
), (err, resp) => (在这里包装了我的数据库查询)。现在 console.log() 正在打印所有值,但使用时返回 volData。显示未定义。我试过 getSingleExchange().then(data => console.log(data) );和 (async () => const data = await getSingleExchange() console.log(data) )();以上是关于从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值的主要内容,如果未能解决你的问题,请参考以下文章
当我直接从 MySQL 获取时,NodeJS 响应 MySQL 时区不同
从 NodeJS 中的 AJAX 请求中获取数据并存储在 DB 中
如何创建从 nodejs mysql 模块获取的正确 json 类型数据?
如何从 Nodejs Mysql 获取 JSON 类型作为 JSON 而不是 String