98

Having an array of objects [obj1, obj2]

I want to use Map function to make a DB query (that uses promises) about all of them and attach the results of the query to each object.

[obj1, obj2].map(function(obj){
  db.query('obj1.id').then(function(results){
     obj1.rows = results
     return obj1
  })
})

Of course this doesn't work and the output array is [undefined, undefined]

What's the best way of solving a problem like this? I don't mind using other libraries like async

Jorge
  • 2,156
  • 2
  • 22
  • 29
  • 14
    This question should not have been marked as a duplicate. This question is specifically about using promises inside `map`, _not_ how does async work in general. – tim-phillips Feb 22 '18 at 15:41

5 Answers5

204

Map your array to promises and then you can use Promise.all() function:

var promises = [obj1, obj2].map(function(obj){
  return db.query('obj1.id').then(function(results){
     obj1.rows = results
     return obj1
  })
})
Promise.all(promises).then(function(results) {
    console.log(results)
})
madox2
  • 49,493
  • 17
  • 99
  • 99
  • how can i match results of promises and data from original model in this case? I want to combine them in starting model – Berk Can Mar 30 '23 at 13:28
  • 1
    the order in the arrays is perserved, so you can use array index to match the data and results – madox2 May 03 '23 at 14:20
20

Example using async/await:

const mappedArray = await Promise.all(
  array.map(p => {
    return getPromise(p).then(i => i.Item);
  })
);
fede1608
  • 2,808
  • 1
  • 16
  • 17
16

You are not returning your Promises inside the map function.

[obj1, obj2].map(function(obj){
  return db.query('obj1.id').then(function(results){
     obj1.rows = results
     return obj1
  })
})
mdziekon
  • 3,531
  • 3
  • 22
  • 32
9

You can also do for await instead of map, and resolve your promises inside of it as well.

Pedro Paes
  • 91
  • 1
  • 2
-1

You can also use p-map library to handle promises in map function.

Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently.

This is different from Promise.all() in that you can control the concurrency and also decide whether or not to stop iterating when there's an error.

Jakub Kurdziel
  • 3,216
  • 2
  • 12
  • 22
  • There is also a more generic [iter-ops](https://github.com/vitaly-t/iter-ops) module that has [waitRace](https://vitaly-t.github.io/iter-ops/functions/waitRace) operator to do the same. – vitaly-t Dec 04 '22 at 12:56
  • it is not necessary to use library to this task – Romanas Dec 21 '22 at 14:01