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!