Closed domenic closed 11 years ago
The only thing I don't like about this is that it makes it hard for extensions like notifyAboutProgress
and cancel
, i.e. it has the problem summed up in #7. I guess it could be specced to pass factory
an object (what's a good name for such an object?) that has resolve
and reject
methods.
Also, I'm leaving thrown errors uncatchable, but could be convinced that they should become rejections. But then we have the whole "what if you do resolve(5); throw 10;
?" issue.
It turns out I had massive confusion over the behavior we want from calling resolve
(or reject
) on a promise that is waiting on a pending promise. In Q:
var d = Q.defer();
d.resolve(Q.delay("a", 1000));
d.resolve("b");
// after 1000 ms, `d.promise` is fulfilled with "a".
As specced here, a d.promise
is not settled when d.resolve("b")
is called, so as specced here, d.promise
would immediately be fulfilled with "b"
.
Thus, replacing this with #18.
Terminology
The Promise Constructor
An implementation of this specification supplies a function responsible for constructing new promises. This promise constructor takes as its sole argument a user-supplied factory function which is given the means to settle the constructed promise.
Here we refer to this promise constructor by the name
Promise
for concreteness, although the name is implementation-specific.new
, with the same results.promise instanceof Promise
must be true.Object.getPrototypeOf(promise) === Promise
must be true.promise.constructor === Promise.prototype.constructor === Promise
must be true.Promise.length === 1
must be true.factory
is not a function, the implementation must throw aTypeError
.factory
is a function,The Factory Parameters
When
factory
is called, it is given two parameters, which we call hereresolve
andreject
. In this way,factory
obtains the means to settle a promise.Calling
resolve(x)
x
is a non-thenable,promise
is pending,promise
must be fulfilled withx
as its fulfillment value.promise
is settled, nothing happens (in particular, no exception may be thrown).x
is a thenable,promise
must attempt to adopt the state ofx
(see Promises/A+ spec).Calling
reject(reason)
promise
is pending,promise
must be rejected withreason
as its rejection reason.promise
is settled, nothing happens (in particular, no exception may be thrown).Thenable Assimilation (Optional)
Optionally, an implementation may provide the capability to "assimilate" thenables, turning them into real promises. If so, this is done with a property
from
of the promise constructor:thenable
is not an object or function, throw aTypeError
.thenable
does not have a propertythen
that is a function, throw aTypeError
.new Promise(thenable.then)
.Notes
setTimeout
,setImmediate
, orprocess.nextTick
to ensure thatfactory
is not called in the same turn of the event loop as the call to the promise constructor. Note that iffactory
throws an exception, it will necessarily be uncatchable and not interfere with any surrounding code, since the execution stack is empty.