0

I have started to learn promises and have encountered a problem with sequencing data in my Vue app. Basically, I need to run a few functions in a specific order where each promise must be fully resolved and essential data must be set before the next function is called. I am currently trying to use Promise.all to achieve this but have had no success so far. The promises appear to resolve and fall through to the next function before the data is ready.

Here is an extract of the code.

  const promisesArray = [this.loadPrivate(),this.loadPublic()]
      await Promise.all(promisesArray).then(() => {
        // Promises resolve and fall through to this function before data has been set
        this.recordsCheck()
      })
      .catch((err) => { console.log('ERR IN PROMISE.ALL', err)})

Here is one of the promises. They are both more or less identical. As you can see it's in TypeScript but I don't think that is part of the problem.

  async loadPublic(): Promise<TODO> {
    new Promise(function(resolve, reject) {
       // classes module is a promised-based API call which sets data to an array in a Vuex store
      classesModule.getPublic().then((results) => {
        // data not ready here yet
        console.log('PUBLIC GROUPS IN DASH PROMISE ', results)
        resolve() // Resolve triggers before the data is ready
      }).catch(e => {
        console.log('ERROR in dash.loadGroupClasses : ', e)
        reject()
      }); 
    });
  }  

For brevity here is the gist of the classesModule.getPublic function.

  @Action async getPublic(): Promise<TODO> {   
    await getPublicGroups("getPublicGroups", data).then(res => {
      // do some work here
      this.records.push(...records)
      // Records have been correctly set here before the resolve
      console.log('Public records array : ', this.records)
      resolve()
  })

The data definitely gets set eventually because I can see it in the console after the entire page has loaded. It just hasn't finished being set by the time the initial promises resolve and recordsCheck function is called, causing undefined errors.

Maybe there is an issue because of the multiple promises? I've kind of hit an impasse with it and would appreciate any help. Thanks in advance!

UPDATE

OK, based on some of the comments below I could see the problem. The functions in Promises.all were not actually returning promises. Yes, a bit of a silly oversight that I think I missed due to the multiple promises in the chain between different modules. So instead of this..

async loadPublic(): Promise<TODO> {
    new Promise(function(resolve, reject) {
     classesModule.getPublic().then((results) => {
        console.log('PUBLIC GROUPS IN DASH PROMISE ', results)
        resolve()
      }).catch(e => {
        console.log('ERROR in load : ', e)
        reject()
      }); 
    });
  }   

I needed to do this...

async loadPublic(): Promise<TODO> {
  return classesModule.getPublic().then((results) => {
        console.log('PUBLIC GROUPS IN DASH PROMISE ', results)    
      }).catch(e => {
        console.log('ERROR in load : ', e)
      }); 
    });
  }  

It appears to work correctly now. Thanks to all for tips. Really helped me out!

mikeym
  • 5,705
  • 8
  • 42
  • 62
  • 1
    `loadPublic` doesn't **return** a promise – Quentin Aug 10 '21 at 18:01
  • ```Promise.all``` will not run the ```Promise``` array in a sequence, it runs them all in parallel – bloo Aug 10 '21 at 18:06
  • 1
    Also, you aren't returning the ```Promise``` in ```loadPublic``` – bloo Aug 10 '21 at 18:09
  • Should it be`return new Promise`? I just tried that but it didn't work and doesn't even reach the `.then` from `Promises.all`. – mikeym Aug 10 '21 at 18:41
  • Sorry, when I say they must run in sequence I mean the functions in the `Promises.all` must run first and the function in the `.then` must run only once they have finished their work. It doesn't matter which of the functions in the promises array finishes first. – mikeym Aug 10 '21 at 18:43
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Aug 10 '21 at 21:02
  • @Siguza One cannot fulfill a promise with another promise, returning promises from `async` functions is fine, it just resolves the result promise. – Bergi Aug 10 '21 at 21:04
  • You should answer your own question and accept it instead of update the question with the answer. It will help people to find the answer easily in the future. – ikhvjs Aug 11 '21 at 11:52

0 Answers0