0

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

Kermit
  • 2,865
  • 3
  • 30
  • 53
  • So to confirm, your question is actually more along the lines of, _"How can I execute multiple promises at the same time?"_ – Dane Brouwer Aug 24 '20 at 13:01

2 Answers2

2

To quote the documentation for both .set and .remove

The effect of the write will be visible immediately, ... the returned Promise will resolve when complete. If provided, the onComplete callback will be called asynchronously after synchronization has finished.

i.e. As soon as you call the .set or .remove method, firebase will attempt to perform the write action.

Re: Using Promise.all

Do you mean this is an incorrect approach when calling Set/Remove?

No, I'm not saying this is an incorrect approach. What I'm saying is that the write action happens immediately, regardless of whether or not you use Promise.all.

All that Promise.all does, is ensure that every promise in the provided array has been resolved.

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

Promise.all

Sources:

Set, Remove

Dane Brouwer
  • 2,827
  • 1
  • 22
  • 30
  • Hi Dane! Thank you for the reply! A common approach is to collect all promises to be carried out and then run Promise.all() to ensure all promises are run synchronously. Do you mean this is an incorrect approach when calling Set/Remove? I have updated my question accordingly. Kind regards /K – Kermit Aug 24 '20 at 11:29
  • Thank you Dane! My confusion was based on the assumption that my Array held the promises to be carried out - not the callbacks (results) from the promises. It is rather obvious to me now. :) /K – Kermit Aug 24 '20 at 14:46
  • I think you may have a misunderstanding of how promises work, I would suggest doing some reading there. – Dane Brouwer Aug 24 '20 at 15:45
  • 1
    For JavaScript promises in Firebase I recommend watching this series: https://www.youtube.com/watch?v=7IkUgCLr5oA – Kermit Aug 25 '20 at 07:29
  • I'll assume this isn't a slight at my understanding of promises, and rather an update on your reading. I'm glad you found a video that clearly outlines promises and how they interact with Firebase. :) – Dane Brouwer Aug 25 '20 at 08:22
2

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.

Lionel Rowe
  • 5,164
  • 1
  • 14
  • 27
  • 1
    `.set` and `.remove` return promises, no need to `await` in `execAsync` as `Promise.all` will do it for you. `await`, in that instance, is just wrapping a promise around another promise. :) – Dane Brouwer Aug 24 '20 at 13:08
  • My confusion was based on the assumption that my Array held the promises to be carried out - not the callbacks (results) from the promises. It is rather obvious to me now. :) /K – Kermit Aug 24 '20 at 14:47