user2954945
user2954945

Reputation: 121

Promises not resolving in the order they were called

I am integrating a website with firebase. I am trying to get user IDs from my users collection in the database and then pass each of the user IDs to another function that gets the experience data from another collection. I order the users by name because i want the users sorted alphabetically on my page. The code works as I have it except that the promises do not resolve in the correct order and thus are not output alphabetically. Please see details below:

  1. First i get the users with the getUserProfiles function.
  2. i confirm each user ID by printing out each index directly (users[0], users[1], users[2]).
  3. I then loop through each user and console log the user ID before and after the database query.
  4. Looking at the console logs, it looks like the user ids are being passed to the database query in the correct order, but the 2nd ID is resolving before the first ID. the first ID passed to the database is 'ZKnqtLVzUqNqdzX9f8ap76LThh32'. Yet, '482uR9t2QEdCUi0Z4nq14VRVhEx1' resolves first

Why are the IDs not resolving in the order that they were passed?

    function getUserProfiles(){
      //get users, usernames and render profiles
        db.getUsers().then(users => {
          console.log('first index:', users[0].id);
          console.log('second index:', users[1].id);
          console.log('third index:', users[2].id);
          users.forEach(user => {
            db.getLatestExperience(user.id).then(()=>{

            })
        })  
    }

    Class {
        getLatestExperience(id, callback) {
          console.log('getLatestExperience before database request:', id);
          return this.experience.where('userID', '==', id).orderBy('start','desc').get().then(snapshot => {            
          console.log('getLatestExperience promise resolved', id);
        })        
      }

     getUsers(callback) {
       return this.users.orderBy('name').get().then(snapshot => {
            return snapshot.docs;
        })
      }
    }


    first index: ZKnqtLVzUqNqdzX9f8ap76LThh32
    second index: 482uR9t2QEdCUi0Z4nq14VRVhEx1
    third index: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
    getLatestExperience before database request: ZKnqtLVzUqNqdzX9f8ap76LThh32
    getLatestExperience before database request: 482uR9t2QEdCUi0Z4nq14VRVhEx1
    getLatestExperience before database request: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
    getLatestExperience promise resolved: 482uR9t2QEdCUi0Z4nq14VRVhEx1
    getLatestExperience promise resolved: ZKnqtLVzUqNqdzX9f8ap76LThh32
    getLatestExperience promise resolved: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2

Upvotes: 0

Views: 53

Answers (2)

Thatkookooguy
Thatkookooguy

Reputation: 7012

You can use Promise.all in order to resolve when all users return. Promise.all have it built in to order the result array the same as the given promises

function getUserProfiles() {
  //get users, usernames and render profiles
  return db.getUsers()
    .then(users => {
      console.log('first index:', users[0].id);
      console.log('second index:', users[1].id);
      console.log('third index:', users[2].id);

      const latestExperiencePerUserPromises = users
        .map((user) => db.getLatestExperience(user.id));

      return Promise.all(latestExperiencePerUserPromises);
    });
}

Upvotes: 0

parohy
parohy

Reputation: 2180

You can put the promises in an array and reduce them so they execute sequential:

const promiseArray = [promise2, promise3...]
    promiseArray.reduce(
        (prev, next) => prev.then(prevResult => next(prevResult)), promise1())
            .then(finalResult => {...})

promiseArray is an array of functions that returns a promise. You leave out the first one, as you need a starting one later. Array.reduce will execute one after another. prev is your previous promise you are resolving and if needed, for the next one, you can resolve it with a result and pass it over to next. Finally at the end you can resolve the whole reduce with one single result from the last promise.

Upvotes: 0

Related Questions