Most times I'm doing something with promises that requires me to pass resolution and rejection functions outside the current promise scope (usually to store in like a queue or something), I find myself replicating promise capabilities, with the constructor being basically NewPromiseCapability(%Promise%):
function newCapability() {
let resolve, reject
let promise = new Promise((res, rej) => {
resolve = res
reject = rej
})
return {resolve, reject, promise}
}
Can we add a Promise.newCapability() that's essentially return NewPromiseCapability(this)? Engines already have to have this logic and they also explicitly optimize for it for native promises, avoiding the overhead of the inner function and just allocating everything at once, and I'd also like to reuse some of these optimizations myself.
That was originally part of ES6, as i recall, as Promise.defer(). Chrome shipped it for awhile, but eventually removed it, since it wasn’t in the spec and no other browsers shipped it. es6-shim also deletes it whenever present, on a lot of websites.
The Deferred pattern you’re describing is indeed the way it’s typically done, but the need for it should be exceedingly rare, and also usually is part of a larger abstraction.
Why would engines have that logic? Non-observable parts of the spec are not necessarily the way engines implement things.
I'm aware, but those larger abstractions do find themselves in many places. The large name is in part to also be a clear discouragement of its usage. It's meant to stick out badly and kind of scream "this isn't generally how you should do this".
I'm referring to specific engine optimizations for that function:
This is the optimization I'm referring to - it's a pretty obvious optimization if you can split promise initialization from promise allocation. And of course, it's actually kind of necessary for engines to implement something similar, even if they're only approximating the spec (as is the case with Hermes with its promise implementation).