Promise capability support

Bob Myers rtm at
Fri Jul 20 04:04:06 UTC 2018

I've used this pattern exactly twice in the large-scale app I'm working on
One of those I was able to eliminate after I thought harder about the
The other I eventually replaced with the following kind of pattern:

function createPromise(resolver, rejector) {
  return new Promise((resolve, reject) {

Obviously the way this works it that to create a promise "controllable"
from "the outside",
you create your own resolver and rejector promises to pass to
such that they trigger when you need them to.
To put it a different way, instead of getting back and passing around
deferred-like objects,
which seems to be a massive anti-pattern to me,
the client creates their own promise-controlling promises designed to
trigger at the right time.


On Fri, Jul 20, 2018 at 9:07 AM Jordan Harband <ljharb at> wrote:

> I don't think the Deferred pattern is a good primitive to have in the
> language, and it's a pretty trivial primitive to write yourself if you need
> it.
> On Thu, Jul 19, 2018 at 6:13 PM, Isiah Meadows <isiahmeadows at>
> wrote:
>> Sometimes, it's *very* convenient to have those `resolve`/`reject`
>> functions as separate functions. However, when logic gets complex
>> enough and you need to send them elsewhere, save a continuation, etc.,
>> it'd be much more convenient to just have a capability object exposed
>> more directly rather than go through the overhead and boilerplate of
>> going through the constructor with all its callback stuff and
>> everything.
>> It's surprisingly not as uncommon as you'd expect for me to do this:
>> ```js
>> let resolve, reject
>> let promise = new Promise((res, rej) => {
>>     resolve = res
>>     reject = rej
>> })
>> ```
>> But doing this repeatedly gets *old*, especially when you've had to
>> write it several dozen times already. And it comes up frequently when
>> you're writing lower-level async utilities that require saving promise
>> state and resolving it in a way that's decoupled from the promise
>> itself.
>> -----
>> So here's what I propose:
>> - `Promise.newCapability()` - This basically returns the result of
>> [this][1], just wrapped in a suitable object whose prototype is
>> %PromiseCapabilityPrototype% (internal, no direct constructor). It's
>> subclass-safe, so you can do it with subclasses as appropriate, too.
>> - `capability.resolve(value)` - This invokes the implicit resolver
>> created for it, spec'd as [[Resolve]].
>> - `capability.reject(value)` - This invokes the implicit rejector
>> created for it, spec'd as [[Reject]].
>> - `capability.promise` - This returns the newly created promise.
>> Yes, this is effectively a deferred API, but revealing constructors
>> are a bit too rigid and wasteful for some use cases.
>> [1]:
>> -----
>> Isiah Meadows
>> me at
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list