Node_Redis 使用 Promise.all 时 HGET 解析为布尔数组

Node_Redis HGET resolving to boolean array when using Promise.all

我一直在研究 redis 并开发一个使用 redis 的小型网络应用程序,因为它只是数据存储(我知道这不是 redis 的预期目的,但我受益于学习命令和整体使用 redis在节点上。我正在使用 Node_Redis.

这是我想要完成的(全部在redis中): 我正在尝试使用他们的电子邮件检索用户。

问题来了: 我有一个 Promise.all 调用,它接受所有电子邮件(密钥)并将每个映射到一个 HGET 命令。当 Promise.all 解析时,我希望它用一组用户对象来解析,但它最终解析为一组布尔值(即 [true, true, true])。

这是/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"]);
    }
  });
});

我实际上已经使用 Promise.all 很多次了,当我记录来自 redis 的回复时,它也显示了正确的对象,所以我现在很困惑。如何让 Promise.all 解析为用户对象数组?

问题是 client.hgetall 没有 return 承诺。它是异步函数,您传递回调以获得结果。您应该 promisify 这个函数以在 Promise.all:

中使用它
...
return new Promise((resolve, reject) => {
  client.hgetall(email, (err, reply) => {
    if (err) {
      return reject(err);
    }
    resolve(reply);
  });
});

您可以手动执行 promisification(如上例所示),或者可以使用 BluebirdQ 库及其 promisifypromisifyAll 方法。