【问题标题】:Node js wait for loop to finish节点js等待循环完成
【发布时间】:2020-04-01 19:03:03
【问题描述】:

我正在尝试返回某个用户喜欢的事件列表,但代码返回的数组似乎总是为空(返回在我的 for 循环之前执行)。

router.route("/app/mylikes").get(async function(req, res, next) {
  var mylikes = [];

  const likes = await Like.find();

  likes.forEach(element => {
    bcrypt.compare(req.user.device_uuid, element.device_uuid, function(
      err,
      isMatch
    ) {
      if (isMatch) {
        mylikes.push(element.event_id);
      }
    });
  });
  res.send(mylikes);
});

用户的 uuid 在表中被散列,所以我先使用 bcrypt 进行比较,然后将其添加到我的“mylikes”数组中。

在 Promises/await/async 方面我仍然是个菜鸟,因此感谢您提供任何帮助。

【问题讨论】:

标签: node.js express promise async-await bcrypt


【解决方案1】:

您正在使用bcrypt.compare 的回调系统,但是当您省略回调参数时,还有一个promise interface for it

for (let element of likes) {
   let isMatch = await bcrypt.compare(req.user.device_uuid, element.device_uuid);
   if (isMatch) {
      mylikes.push(element.event_id);
   }
}

确保使用is compatible with your version of Node 的bcrypt 版本。

如果由于某种原因您无法迁移到 bcrypt 3(我会问“为什么?”),那么您可以按如下方式承诺 compare 方法的非承诺版本:

let comparePromise = (str, hash) => 
    new Promise((resolve, reject) =>
        bcrypt.compare(str, hash, (err, isMatch) =>
            err ? reject(err) : resolve(isMatch)
        )
    );

然后:

for (let element of likes) {
   let isMatch = await comparePromise(req.user.device_uuid, element.device_uuid);
   if (isMatch) {
      mylikes.push(element.event_id);
   }
}

请注意,您不能在其回调中使用.forEachawait,因为这不会停止forEach 迭代以暂停。这就是我使用for...of 循环的原因。

【讨论】:

  • 哪一行?对于bcrypt.compare?您使用的是哪个版本的节点和 bcrypt?请参阅documentation,其中甚至有一个示例:match = await bcrypt.compare(password, user.passwordHash);
  • 使用 bcrypt 2.0.2 和节点 10.16.3
  • 哪一行?根据 bcrypt 文档中的表格,对于 Node 10+,您应该使用 bcrypt 版本 3+
  • bcrypt.compare 行
  • 您使用的 bcrypt 版本不保证与节点 10 兼容。
猜你喜欢
  • 2017-05-03
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
  • 2021-09-17
  • 2020-11-10
  • 1970-01-01
相关资源
最近更新 更多