I am trying to execute multiple Promise.all()
in sequence and wait for each Promise.all()
to finish before proceeding and then return Promise.resolve()
.
In essence I want to
My code lives in a Firebase Realtime database trigger event.
The problem I am experiencing is that the database function finishes too early, before all promises are resolved. Why does the function finish before ALL promises are completed?
return Promise.all(firstPromises)
.then((firstResult) => {
// Proceed move data from firstPromises to another location
let movePromises = []
movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/1`, to:'one'}))
movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/2`, to:'two'}))
movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/3`, to:'three'}))
movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/4`, to:'four'}))
return Promise.all(movePromises)
})
.then((moveResult) => {
// Result from Promise.all(movePromises)
// Clean up
return Promise.all(cleanPromises)
})
.then((cleanResult) => {
// Result from Promise.all(cleanPromises)
return Promise.resolve(true)
})
.catch((err) => {
console.error('Error', err)
// Clean up
cleanPromises.push(myFunc.cleanup({dbRoot, path:tmpPath}))
return Promise.all(cleanPromises)
// return Promise.reject(err)
})
myFunc.moveStuff():
moveStuff : ({dbRoot, from, to}) => {
console.log(`moveStuff from '${from}' --> '${to}'`)
let myPromises = []
dbRoot.child(from).once('value', (snaps)=>{
console.log(`${from} to move:`, snaps.numChildren())
snaps.forEach((node)=>{
const path = `${to}/${node.key}`
const nodeData = node.val()
myPromises.push(
dbRoot.child(path).set(nodeData)
.then((writeRes)=> {
return dbRoot.child(from).remove()
})
.then((deleteRes)=>{
return Promise.resolve(true)
})
.catch((e)=>{
console.error('moveStuff error', e)
return Promise.reject(e)
})
)
})
})
return myPromises
}
This is my console logout:
cleanup my/SYSTEM
moveStuff from '/my-tmp/SYSTEM/1' --> 'one'
moveStuff from '/my-tmp/SYSTEM/2' --> 'two'
moveStuff from '/my-tmp/SYSTEM/3' --> 'three'
moveStuff from '/my-tmp/SYSTEM/4' --> 'four'
Function execution took 3473 ms, finished with status: 'ok'
/my-tmp/SYSTEM/1 to move: 9
/my-tmp/SYSTEM/2 to move: 100
/my-tmp/SYSTEM/3 to move: 0
/my-tmp/SYSTEM/4 to move: 22
Kind regards /K
I solved the problem by clarifying the execution process with more console logs and implementation of async/await.
moveStuff()
moveStuff : async ({dbRoot, from, to}) => {
let myPromises = []
await dbRoot.child(from).once('value', (snaps)=>{
console.log(`moveStuff from '${from}' --> '${to}'`)
console.log(`${from} to move:`, snaps.numChildren())
snaps.forEach((node)=>{
const path = `${to}/${node.key}`
const nodeData = node.val()
myPromises.push(
dbRoot.child(path).set(nodeData)
.then((writeRes)=> {
return dbRoot.child(from).remove()
})
.then((deleteRes)=>{
return Promise.resolve(true)
})
.catch((e)=>{
console.error('moveStuff error', e)
return Promise.reject(e)
})
)
})
})
return myPromises
}
Promise chain:
return Promise.all(firstPromises)
.then((firstResult) => {
// Proceed move data from firstPromises to another location
console.log('First finished')
let movePromises = []
movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/1`, to:'one'}))
movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/2`, to:'two'}))
movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/3`, to:'three'}))
movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/4`, to:'four'}))
return Promise.all(movePromises)
})
.then((moveResult) => {
// Result from Promise.all(movePromises)
console.log('Move finished')
// Clean up
return Promise.all(cleanPromises)
})
.then((cleanResult) => {
console.log('Clean finished')
// Result from Promise.all(cleanPromises)
return Promise.resolve(true)
})
.catch((err) => {
console.error('Error', err)
// Clean up
cleanPromises.push(myFunc.cleanup({dbRoot, path:tmpPath}))
return Promise.all(cleanPromises)
// return Promise.reject(err)
})
My logout now shows
First finished
Move finished
Clean finished
Function execution took 3473 ms, finished with status: 'ok'