猫鼬顺序承诺

时间:2017-03-25 13:48:33

标签: javascript mongoose promise bluebird

我正在尝试按顺序执行一些动态查询,但出于任何原因,下一个代码无法实现所需的行为。

var createEvent = function (user, notification) {
  var action, query;

  query = { agent: notification.agent, story: notification.story, type: notification.type };
  action = { agent: notification.agent, story: notification.story, type: notification.type, ts: notification.ts };

  return mongoose.model('Event').findOne(query).exec()
    .then(function (response) {
      if (response === null) {
        return mongoose.model('Event').create(action)
          .then(function (response) {
            return mongoose.model('User').findByIdAndUpdate(user, { $push: { notifications: { _id: response._id }}});
          });
      }
      return mongoose.model('User').findByIdAndUpdate(user, { $push: { notifications: { _id: notification._id }}}).exec();
    });

  setTimeout(resolve, 3000);
};

var moveNotifications = function (users) {
  var promises = [];

  users.map(function (user) {
    if (user.notifications.length > 0) {
      user.notifications.map(function (notification) {
        promises.push(createEvent(user._id, notification));
      });
    }
  });

  Promise.each(promises, function (queue_item) {
    return queue_item();
  });
};

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

当您在嵌套的createEvent循环中调用Array#map时,您将立即启动所有查询 - 您要做的只是获取id和{{的数组1}}稍后传递到notification

中的createEvent

注意:不确定为什么使用Promsise.each,因为你永远不会从地图回调中返回任何内容 - 你基本上在做Array#map

Array#forEach

或者,使用var moveNotifications = function(users) { var items = []; users.forEach(function(user) { if (user.notifications.length > 0) { user.notifications.forEach(function(notification) { items.push({id: user._id, notification: notification}); }); } }); return Promise.each(events, function(item) { return createEvent(item._id, item.notification); }); } 展平通过正确使用(嵌套)Array#concat返回的2级数组,可以获得相同的结果

Array#map

使用以下ES2015语法可以更加简洁地进行上述操作:

  • arrow functions var moveNotifications = function(users) { return Promise.each([].concat.apply([], users.map(function(user) { return user.notifications.map(function(notification) { return {id: user._id, notification: notification}; }); })), function(item) { return createEvent(item._id, item.notification); }); }
  • 展开运营商=>
  • 简写对象属性名称...
  • 解构分配 - 参数上下文匹配{a, b, c}
({a, b, c}) =>

极端ES2016单线版:p

var moveNotifications = users => 
    Promise.each([].concat(...users.map(user => 
        user.notifications.map(notification => ({id: user._id, notification}))
    )), ({id, notification}) => createEvent(id, notification)
);