在Node.js中从mySQL获取数据时,如何从Async / await函数获取返回值

时间:2019-06-01 11:34:46

标签: mysql arrays node.js async-await

我正在从数据库中获取一些交换数据,然后提取不同交换的名称,然后再次传递到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)
});

我现在收到此错误:

  

(节点:30583)UnhandledPromiseRejectionWarning:TypeError:db.connection.query(...).then不是函数
  在Promise(/getExchanges.js:217:16)
  在新的Promise()
  在Promise.all.exchanges.map(/getExchanges.js:145:16)
  在Array.map()
  在getSingleExchange(/getExchanges.js:144:33)

1 个答案:

答案 0 :(得分:2)

主要问题在这一部分:

await Promise.all(exchanges.map(async (item) => {

map回调不返回任何内容,并且没有await,因此使用async毫无意义。

请删除async

await Promise.all(exchanges.map((item) => {

...并在回调函数中返回promise,就像您在第一个函数中所做的一样:

    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函数不会同步返回异步结果,而是为其返回承诺。因此,您的最后几行(主要代码)仍应等待。因此,要么这样做:

(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