I've used this pattern exactly twice in the large-scale app I'm working on now. One of those I was able to eliminate after I thought harder about the problem. The other I eventually replaced with the following kind of pattern:
``` function createPromise(resolver, rejector) { return new Promise((resolve, reject) { resolver.then(resolve); rejector.then(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 `createPromise`, 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. Bob On Fri, Jul 20, 2018 at 9:07 AM Jordan Harband <ljh...@gmail.com> 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 <isiahmead...@gmail.com> > 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]: https://tc39.github.io/ecma262/#sec-newpromisecapability >> >> ----- >> >> Isiah Meadows >> m...@isiahmeadows.com >> www.isiahmeadows.com >> _______________________________________________ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss