如何在for循环中进行异步函数

时间:2017-05-07 11:21:07

标签: javascript node.js

首先,我正在为用户所属的所有群组搜索 GroupMember 模型。当他们发现我得到了结果。

我想遍历结果并从模型中获取每个组。但是如何在 for / forEach 中执行异步函数并仅在异步函数完成时转到下一次迭代?

因为现在groups数组将反复进行第一次迭代。

GroupMember.findAll({
    Where : {
      userID : userID
    }
  })
  .then(function(result) {
    var groups = []
    var itemsProcessed = 0;

    result.forEach(function(listItem, index, array) {
      var groupID = listItem.dataValues.groupID;

      Group.find({
        Where : {
          groupID: groupID
        }
      })
      .then(function(group) {

        groups.push(group.dataValues);
        itemsProcessed++;
        if(itemsProcessed === array.length) {

          done(null, groups);
        }
      });
    })

  })
  .catch(function(error) {
    done(error);
  });

修改

群组模型

module.exports.getMyGroups = function(userID) {

  return GroupMember.findAll({ attributes: ['groupID'], where: { userID: userID } })
      .then(function(result) {
        return Promise.all(result.map(function(listItem) {
            var groupID = listItem.dataValues.groupID;

            return Group.find({
              attributes: ['groupName', 'groupDescriptionShort', 'createdAt'],
              where: { id: groupID }
            })
                .then(function(group) {
                  return group.dataValues;
                });
        }));
      });

}

调用模型的组控制器

module.exports.myGroups = function(req, res) {
  var userID = req.body.userID;

  group.findByUserId(userID).then(
    function(groups) {
      respHandler.json(res, 200, { "groups": groups });
    },
    function(error) {
      respHandler.json(res, 400, { "error": error });
    });
}

路由器呼叫组控制器

router.post('/groups', groupCtrl.myGroups);

1 个答案:

答案 0 :(得分:1)

您可以使用Promise.all更好地处理多个类似承诺的执行。

  GroupMember.findAll({
    Where : {
      userID : userID
    }
  })
  .then(function(result) {
     return Promise.all(result.map(function (listItem) {
        var groupId = listItem.dataValues.groupID;

        return Group.find({ Where: { groupId: groupId })
                    .then(function (group) {
                         return group.dataValues;
                    });
     }));
   })
   .then(function (groups) {
      done(null, groups);
   })
   .catch(function(error) {
      done(error);
   });

但是如果你真的需要等到每次迭代才能进入下一次迭代,我会使用其他一些功能

GroupMember.findAll({
    Where: { userId: userId }
}).then(function (result) {
    var array = [];

    function next () {
        var groupId = result[array.length].dataValues.groupId;

        Group.find({ Where: { groupId: groupId })
             .then(function (group) {
                 array.push(group.dataValues);

                 if (array.length >= result.length) {
                     done(null, array);
                 } else {
                     next();
                 }
             })
             .catch(function (error) {
                 done(error);
             });
    }(); // Directly executed
})
.catch(function(error) {
   done(error);
});