0

I've got a problem structuring my async code. All database-operations are async and return Promises.

I need to find a bunch of Items in the database, change them, then save them and only after all have been saved, continue with the next step in my program flow.

How can I solve this using ES6 promises?

Here is some pseudo-code illustrating my problem:

 database.find("Items").then(results => {
   results.forEach(result => {
      result.name = "some different name";
      database.save(result) // <-- is also async as find
   });
   return true;
 }).then(next) {
   // Only start here after all database.save() have been resolved
 });
Hedge
  • 16,142
  • 42
  • 141
  • 246
  • Possible duplicate of [How do I make this async foreach loop work with promises?](http://stackoverflow.com/questions/23069380/how-do-i-make-this-async-foreach-loop-work-with-promises) – Esteban Jan 12 '16 at 18:04
  • Are you unhappy with the answers you got? Either comment your thoughts or remaining issues, or react otherwise please – Amit Jan 12 '16 at 18:19
  • @Amit I was unhappy with how I posed my question. – Hedge Jan 12 '16 at 18:26

2 Answers2

1

You can use Promise.all():

database.find("Items").then(results => {
   return Promise.all(results.map(result => {
      result.name = "some different name";
      return database.save(result) // <-- is also async as find
   }));
 }).then(() => {
   // Only start here after all database.save() have been resolved
 });
Amit
  • 45,440
  • 9
  • 78
  • 110
1

Use Promise.all to wait for multiple promises - it takes an array (of variable length) of promises.

database.find("Items").then(results => {
    var promises = results.map(result => {
//                         ^^^
        result.name = "some different name";
        return database.save(result);
//      ^^^^^^
    });
    return Promise.all(promises);
}).then(saves => {
//      ^^^^^ an array of the results from the save operations
    …; // starts after all database.save() promises have been resolved
});
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • The `saves` callback is missing the arrow FYI. – loganfsmyth Jan 12 '16 at 18:39
  • @loganfsmyth & FelixKling: Thanks, I overlooked that when editing the OP code – Bergi Jan 12 '16 at 18:48
  • I sometimes also get an Array-like object form the db `{'1': 'obj1', '2':'obj2'}` I need to traverse in the same way as above. I traverse it using `for..in`. How would I write that since there's no callback I can return of like with `.map()` ? – Hedge Jan 12 '16 at 19:14
  • 1
    Just generate an array of promises in that loop. You don't need to use `Array map`. – Bergi Jan 12 '16 at 19:21