4

Actually, I don't know how to check this on real Promise super class, so I'm testing it with a class extending it. But it seems to me the result would be the same.

class PromisePlus extends Promise {
  constructor (handler) {
    super(handler)

    console.log('new promise created')
  }
}

new PromisePlus((resolve, reject) => {
  resolve()
}).then(() => {
  return 'GOOD'
}).then(msg => {
  console.log(msg)
})

prints 'new promise created' 3 times

new PromisePlus((resolve, reject) => {
  resolve()
}).then(() => {
  return PromisePlus.resolve('BAD')
}).then(msg => {
  console.log(msg)
})

prints 'new promise created' 5 times.

The same result with returning new Promise inside then handler

new PromisePlus((resolve, reject) => {
  resolve()
}).then(() => {
  return new PromisePlus((resolve, reject) => {
    resolve('BAD')
  })
}).then(msg => {
  console.log(msg)
})

Obviously, PromisePlus.resolve() creates new promise, but why does returning PromisePlus.resolve() inside then cause one more extra promise creation?

humkins
  • 9,635
  • 11
  • 57
  • 75
  • Because you are returning a new Promise when using `Promise.resolve`. You can return a new promise rejecting as well `Promise.reject(new Error("some error"))` – HMR Apr 23 '18 at 16:39
  • Possible duplicate of [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – zero298 Apr 23 '18 at 16:40
  • 1
    @zero298 That has nothing to do with this question. He's asking about using [Promise.resolve](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve) inside a `then` callback. Specifically wondering why that creates two new promises. How the original promise was created is irrelevant, and it makes sense to use the Promise constructor for a MCVE. – Paul Apr 23 '18 at 16:45
  • He could've asked why `PromisePlus.resolve( ).then( _ => PromisePlus.resolve() )` creates four promises if he wanted to avoid the Promise constructor, but it's the same question and that duplicate doesn't answer it. – Paul Apr 23 '18 at 16:51
  • 1
    Every `.then()` or `.catch()` returns a new promise. – jfriend00 Apr 24 '18 at 00:16
  • @jfriend00 yes, that is why 4 new promise creation was expected, but not 5 – humkins Apr 24 '18 at 09:12

1 Answers1

4

Why does returning PromisePlus.resolve() inside then cause one more extra promise creation?

Because when you are returning a promise from a then callback, it does get awaited to resolve the outer promise (the one returned from .then()). To await this inner promise, .then(…) gets called on it - and this call does create a new promise as well.

(Yes, all this is horribly inefficient, which is probably the #1 reason why promise subclassing should be avoided).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • @BenjaminGruenbaum Will they also remove recursive assimilation? – Bergi Apr 23 '18 at 21:05
  • No of course not - people are actually using that. Not that I think they'd build it with it today. – Benjamin Gruenbaum Apr 23 '18 at 21:43
  • @BenjaminGruenbaum I meant repeated attempts to recursively assimilate already-fulfilled promises, not recursive assimilation in general (in `Promise.resolve`) – Bergi Apr 23 '18 at 21:56