2017-03-25 9 views
0

私はいくつかの動的クエリを順次実行しようとしていますが、何らかの理由で次のコードがその目的の動作を満たしていません。mongoose sequential promises

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(); 
    }); 
}; 

誰かが私を助けてくれますか?ネストされたArray#mapループの内部createEventを呼び出していると

+0

カップル... 'のsetTimeout(決意、3000);' 'return'の後にあるので実行されることはありません - しかし、それだけでも' resolve'はとにかく定義されていません。第2に、あなたは.mapコールバックで 'createEvent'を呼び出します - そのため、それらのすべての' findOne'呼び出しは、最初の.thenが呼び出される前に「飛行中」です。 –

答えて

1

、あなたは一度にすべてのクエリを開始している - あなたが何をしたいのかされてちょうど後でPromsise.each

ノートにcreateEventに渡すidnotificationの配列を取得します: - あなたは基本的にArray#concatを使用して、代わりに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#mapを使用する理由

  • 矢印:(ネストされた)を使用して返された2レベルの配列Array#mapを平らにするために、正しく、あなたは

    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); 
        }); 
    } 
    

    上記やすい次ES2015の構文を使用して、より簡潔に作られて同じ結果を得ることができます機能=>

  • 広がりオペレータ...
  • 速記オブジェクトのプロパティ名{a, b, c}
  • 分割代入 - ({a, b, c}) =>

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

極端ES2016 1つのライナーバージョンをマッチングパラメータコンテキスト:P物事の

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

私は反復的約束を作成するという概念を理解していませんでした!この返答をいただきありがとうございます。私はそれをさらに明確にしています!ありがとう! – DevStarlight