nodeboi
nodeboi

Reputation: 45

Promises: How to resolve an unknown amount of promises

I have a function that takes in an unknown amount of building id's in an array i.e [4,5] and then calls a function which returns it's name and description. I don't know how to approach this given that it is an unknown amount. I tried creating a for loop but that led nowhere and I'm completely lost. What you see below is me sending an entire array to a function, but I want to loop through each element and call the function individually

Edit: Thank you everybody for the kind replies. You have been very helpful and supportive

function getBuilding(buildingId){
      return new Promise(function(resolve,reject){
          Building.getBuilding(buildingId).then((buildingInfo)=>{
              resolve(buildingInfo);
          }); 
      })
}

Upvotes: 1

Views: 2870

Answers (4)

Get Off My Lawn
Get Off My Lawn

Reputation: 36311

You want to use Promise.all, the promise of all will resolve once all the items in the array have also resolved. This then will return a promise with an array of the results where the first item is the first building id result, the second is the second id, and so on.

function getBuilding(ids) {
  let promises = []
  // We will assume `getInfo()` returns a promise that resolves the buildings info
  ids.forEach(id => promises.push(getInfo(id)))
  return Promise.all(promises)
}

function getInfo(id) {
  // Resolves the info after a random amount of time to simulate
  // something that may take some time to execute.
  return new Promise(resolve => setTimeout(() => resolve({id}), Math.floor(Math.random() * 5000)))
}

console.log('Just a moment, calculating data...')
getBuilding([3, 5, 7, 9]).then(results => {
  console.log('building id', results[0].id) // buildingId = 3
  console.log('building id', results[1].id) // buildingId = 5
  console.log('building id', results[2].id) // buildingId = 7
  console.log('building id', results[3].id) // buildingId = 9
})

Upvotes: 6

Wilhelmina Lohan
Wilhelmina Lohan

Reputation: 3043

I think spread operator and Promise.all

function getInfos(...ids) {
  return Promise.all(ids.map(id => Building.getBuilding(id )));
}

//      can be any number of params
getInfos(id1, id2, id3).then(([info1, info2, info3]) => {
  // do stuff
});

I saw in an other comment buildingId is array, in that case:

const buildingId = [1, 2, 3];
getInfos(...buildingId).then(([info1, info2, info3]) => {
  // do stuff
});

or simplified

function getInfos(ids) {
  return Promise.all(ids.map(id => Building.getBuilding(id )));
}

const buildingId = [1, 2, 3];
getInfos(buildingId).then(([info1, info2, info3]) => {
  // do stuff
});

Upvotes: 2

Crisoforo Gaspar
Crisoforo Gaspar

Reputation: 3830

You can use Promise.all which takes and iterable which in this case can be an array.

Like:

function caller( ...promises ) {
    Promise.all( promises ).then( function( value ) {
      console.log( 'all completed' );
    });

}

Where promises is basically an array of arguments, take a look at:

Upvotes: 2

GifCo
GifCo

Reputation: 1363

The Promise.all() method takes an array of promises and waits till they all resolve.

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});

Note that if any one of the promises fail Promise.all() will fail.

Upvotes: 3

Related Questions