I've been digging into redis and working on a tiny webapp that uses redis as it's only data storage (I know it's not the intended purpose of redis but I am benefitting from learning the commands and just overall working with redis on Node. I'm using Node_Redis.
Here's what I want to accomplish (all in redis): I am try to retrieve the users using their emails.
Here's the problem: I have a Promise.all call which takes all emails (keys) and maps each to go a HGET command. When the Promise.all resolves I expect it to resolve with an array of user objects, but it ends up resolving to an array of booleans (i.e. [true, true, true]).
Here is the logic for /users
router.get("/", (req, res) => {
client.lrange("emails", 0, 1, (err, reply) => {
if (err) return console.log(err);
if (reply) {
Promise.all(
reply.map(email => {
return client.hgetall(email, (err, reply) => {
if (err) return console.log(err);
console.log("reply for hgetall", reply); // this prints a user object correct, but Promise.all still resolves to boolean array :(
return reply;
});
})
)
.then(replies => {
// replies = [true, true, true ...]
res.send(replies);
})
.catch(e => console.log(e));
} else {
res.send([reply, "reply is null"]);
}
});
});
I've actually used Promise.all plenty of times, and when I log the reply from redis, it shows the correct object too, so I'm pretty confused at this point. How can I get Promise.all to resolve to an array of User objects?
The problem is that
client.hgetall
doesn't return a promise. It's async function and you pass a callback to get a result. You should promisify this function to use it inPromise.all
:You can do promisification manually (as in example above) or can use
Bluebird
orQ
libraries with theirpromisify
andpromisifyAll
methods.