Problem with async/await while using .forEach
Asked Answered
P

1

5

I'm making a simple Redis' request which is supposed to return all VALUES (not keys) in my database. The problem is that my function returns tab before the .forEach even starts. Why do I know that? My console.log(tab)'s result is printed before console.log(cards) for each iteration. My interpreter also tells me inside the .forEach function that "Promise returned from forEach argument is ignored". What have I done wrong there? Why isn't async/await working inside .forEach?

router.get("/", async (req, res) => {
    try {
        const keys = await client.keys("*")
        //console.log(result)
        const tab = []
        await keys.forEach(async (key) => {
            const cards = await client.smembers(key)
            console.log(cards)
            tab.push(cards)
        })
        console.log(tab)
        return res.send(tab)
    } catch (err) {
        console.error(err)
    }

});
Phasia answered 3/11, 2021 at 17:29 Comment(3)
forEach doesn't return a promise which is why you're getting that warning.Shake
how about reduce or map? would it work with them? I'd like to avoid using loopsPhasia
You'll still be iterating over an array with map or reduce. Maybe create an array of promises and await Promise.all instead.Shake
T
7

forEach is not meant to work with async functions. You can use a for ... of loop instead.

for(const key of keys){
    const cards = await client.smembers(key)
    console.log(cards)
    tab.push(cards)
}
Transceiver answered 3/11, 2021 at 17:31 Comment(3)
how about reduce or map? would it work with them? I'd like to avoid using loopsPhasia
@Phasia None of those work with async functions or Promises. Sometimes a simple for loop is the easiest.Transceiver
A little further explanation. While the async foreach runs in the original question, the observed outcome is because it's just doing multiple async calls. async will run in parallels with the rest of the logic, which is why he sees that the console.log(tab) is returned before his async foreach. And as noted in this answer, for of is the solution to this problem.Risinger

© 2022 - 2024 — McMap. All rights reserved.