Search code examples
javascriptfirebase-realtime-databasees6-promise

Firebase realtime database - add .remove() to promise array executes before Promise.all()


I am adding a set of instructions to be performed by Promise.all() at the end of my code. What I have noticed is that the .remove() instructions are executed even if Promise.all() is NOT called. (??)

My code:

const myObject = { test:1 }
let myPromises = []
// This .set() will not get executed since I am not calling Promise.all()
console.log(`dbRoot.child('${path}/${uid}/${id}').set(myObject)`)
myPromises.push(dbRoot.child(`${path}/${uid}/${id}`).set(myObject))
// This .remove() gets executed at once, even though Promise.all is never called
console.log(`dbRoot.child('${path}/${uid}/${id}').remove()`)
myPromises.push(dbRoot.child(`${path}/${uid}/${id}`).remove())

// These lines have been excluded to prevent promises from being carried out
/*
return Promise.all(myPromises)
.then(result => Promise.resolve(true))
.catch((err)=>{
  console.error('error', err)
  return Promise.reject(err)
})
*/

I have checked my code and .set(null) or .remove() is not called from anywhere else but these lines.

How can I collect all .set() and .remove() and carry them all out at once synchronously? (Maybe using Promise.all ?)

Kind regards /K


Solution

  • If you don't want a promise to execute immediately, simply wrap it in a function. You can then execute each function only when you call Promise.all:

    const actions = [
      () => dbRoot.child(`${path}/${uid}/${id}`).set(myObject),
      () => dbRoot.child(`${path}/${uid}/${id}`).remove(),
    ]
    
    ;(async () => {
      const results = await Promise.all(actions.map(fn => fn()))
    
      console.log(results)
    })()
    

    Note that Promise.all executes promises in parallel. If you instead want them executed in series, use Array#reduce or for await ... of instead.