节点js等待循环完成

时间:2019-12-08 13:39:25

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

我试图返回某个用户喜欢的事件列表,但是代码返回的数组似乎总是空的(返回在我的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方面,我仍然是菜鸟,所以可以提供任何帮助。

1 个答案:

答案 0 :(得分:2)

您正在使用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循环的原因。