【问题标题】:How to get return values from Async/await function when fetching the data from mySQL in Nodejs从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值
【发布时间】: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)

【问题讨论】:

    标签: mysql arrays node.js async-await


    【解决方案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) })();
    猜你喜欢
    • 1970-01-01
    • 2020-03-12
    • 2019-03-01
    • 2019-09-13
    • 2021-08-06
    • 2020-09-09
    • 2019-02-25
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多