Parameter to promise constructor
Domenica Denicola wrote:
Since there's no real advantage to the
PromiseResolver
approach, and there are a number of disadvantages, we were hoping to switch to the prevalent(resolve, reject)
signature in the revised DOM promises spec.Let us know what you think!
One advantage to the PromiseResolver
is that it's easier to pass around than two separate functions. Passing the resolver around isn't common, but at my workplace we've made use of it in a "requester" pattern.
function Requester() { this.requests = Object.create(); } Requester.prototype = { respond: function(requestName, callback) { this.requests[requestName] = callback; }, request: function(requestName, ...values) { return new Promise(resolver => { this.requests[requestName](resolver, ...values); }); } };
This allows a general data retrieval mechanism to easily be dropped in place. For instance, if you are writing a Grid class which should display tabular data and it needs to request new data any time the page is changed or columns or sorted, you can make it a requester. Then whoever creates a Grid can define how it gets its data:
var grid = new Grid(); grid.respond('load-data', function(resolver, page, sorts) { var request_params = { // ... page: page, sorts: sorts, // ... }; makeAjaxCall(request_params).then(data => { resolver.resolve(data); }); });
Whenever the grid wants to load data, it will internally make a "load-data" request.
All of these things could be written to use resolve
and reject
functions rather than a PromiseResolver
object, but having one thing to pass around has been nice in my experience (we call that thing the "Obligation" because if you get it it's your obligation to fulfill the promise).
Note that this turns the common use case on its head. The creator of the promise passes the resolver to the outside party and holds onto the promise itself. That's why it's been helpful two full objects with different roles.
On Fri, Aug 30, 2013 at 7:33 AM, Nathan Wall <nathan.wall at live.com> wrote:
One advantage to the
PromiseResolver
is that it's easier to pass around than two separate functions. Passing the resolver around isn't common, but at my workplace we've made use of it in a "requester" pattern.function Requester() { this.requests = Object.create(); } Requester.prototype = { respond: function(requestName, callback) { this.requests[requestName] = callback; }, request: function(requestName, ...values) { return new Promise(resolver => { this.requests[requestName](resolver, ...values); }); } };
Just change this to:
this.requests[requestName]({resolve, reject}, ...values);
Changing the argument signature has only a tiny, local effect on your code.
Passing around just the resolve function is another way to encode that same functionality with no loss of generality, since one can call the resolve with a rejected promise, in order to reject the previously returned promise. The reject function is just a convenience for that.
(The resolve function by itself is also an attenuation of the resolve function, though this is not relevant to the current example since it would be bundled with the resolve function, negating any attenuation.)
Anne, Mark, and I are working through the details on revising DOM promises to match the updated AP2 consensus we've developed over these many es-discuss promise threads. There is one change we were hoping to make from the DOM promises spec that has not been discussed before, so we wanted to run it by the list to make sure there were no objections.
All existing promise implementations that use the constructor pattern, e.g. Q, WinJS, YUI, RSVP, when, then/promise, and others, give the constructor arguments as
new Promise((resolve, reject) => ...)
. This was codified in a Promises/A+ strawman which has met with wide agreement among the implementer community.The current DOM promises draft gives the constructor arguments as
new Promise(resolver => ...)
whereresolver
is an instance of thePromiseResolver
class and hasresolve
,reject
, andfulfill
methods. With the AP2 changes,fulfill
no longer is necessary (you will usePromise.of
for that use case), so this would be reduced toresolve
andreject
methods. Note thatPromiseResolver
is a full-fledged constructor with its own prototype, and theresolve
andreject
methods are actually methods, i.e. can't be extracted without binding, so in particular using destructuring syntax likenew Promise(({ resolve, reject }) => ...)
will not work.Since there's no real advantage to the
PromiseResolver
approach, and there are a number of disadvantages, we were hoping to switch to the prevalent(resolve, reject)
signature in the revised DOM promises spec.Let us know what you think!