Open domenic opened 11 years ago
I like it. Things to consider:
then
throws an errorresolve
polymorphicMy thoughts:
1: Simple, lots of implementations already provide an onProgress
argument to then.
2: Could be as simple as:
let promise = when({ then(resolve, reject) => resolve(5),
cancel() => xhr.abort() });
3: I think it should be equivalent to calling reject
4: not sure yet
The more small failings I see with other ideas the more I like this one. Everything that's really hard to get right for any other spec is really easy with this one.
I still think it should be a constructor, so that:
promise instanceof Promise
is always true.
let promise = new When((resolve, reject) => resolve(5));
let promise = new When({ then(resolve, reject) => resolve(5) });
This is definitely interesting, and I'm personally a fan of the functional style.
I believe that when.js and Q are both effectively compliant with this proposal.
Given that each library will have their own Promise
constructor, what are the near-term advantages of promise instanceof Promise
over the standard duck type test? Or is the primary benefit looking (waaay) ahead to the day when there is some official Promise constructor?
The advantage of the promise constructor is as in #5: it allows utility libraries to create promises that match those of the implementation in use. I.e., in this case:
function timeout(promise, time) {
var Promise = promise.constructor;
return new Promise({ then: function (resolve, reject) {
promise.then(resolve);
setTimeout(function () {
reject(new Error('Operation timed out.'));
}, time);
} });
}
I think it's a bit awkward to have the constructor use the assimilation signature, though, thus what I proposed in #18.
I really only want the constructor stuff for discoverability, and perhaps we should do that another way and in another spec. We'd still have real problems deciding whether the constructor we'd found was a Resolvers/A+ constructor anyway.
Provided people agree with me that: when then
throws an error we turn that into a rejection I'm fully in favor of going forward with just specifying assimilation as our only construction method (assuming we can get buy in from the library authors).
Even though I understand how this would work, it seems too weird a concept creating promises through assimilation. "I have to call when()
, and pass it an object that has a then()
, but I'm not calling then()
, it gets called for me… argh just let me have defer()
!"
This came out of a discussion with MarkM and @kriskowal. It seems promising.
Start from this formulation of the "promise constructor" idea we've seen in many other issues so far:
Imagine if instead we specced a thenable assimilator, we'll call it
when
. Then we could instead accomplish the above with:This is between one and three more characters, depending on if you prefer
{x:y}
or{ x: y }
.ES6 style:
This time between -1 and +1 character deltas.
Q of course gets it easy, because our assimilator would be called
Q
, making it a win on characters in every case.Important note:
then
must be executed in the next turn of the event loop to prevent malicious thenables from breaking execution flow. (On the plus side, this means that any calls toresolve
orreject
can synchronously inform the returnedpromise
, since we're already in the next tick.)Alternately we could spec both assimilation and construction at the same time, given an equivalence between two. Maybe
new Promise((resolve, reject) => { ... })
is equivalent toPromise.from({ then(resolve, reject) => { ... })
?