Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strawman: Promise Creation API/C #17

Closed
domenic opened this issue Feb 10, 2013 · 3 comments
Closed

Strawman: Promise Creation API/C #17

domenic opened this issue Feb 10, 2013 · 3 comments

Comments

@domenic
Copy link
Member

domenic commented Feb 10, 2013

Terminology

  1. "Settled" means either fulfilled or rejected.

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.

var promise = new Promise(factory);
  1. Can be called without new, with the same results.
  2. promise instanceof Promise must be true.
  3. Object.getPrototypeOf(promise) === Promise must be true.
  4. promise.constructor === Promise.prototype.constructor === Promise must be true.
  5. Promise.length === 1 must be true.
  6. If factory is not a function, the implementation must throw a TypeError.
  7. If factory is a function,
    1. It must be called with the factory parameters.
    2. It may only be called when the function execution stack is empty. (note 1)

The Factory Parameters

When factory is called, it is given two parameters, which we call here resolve and reject. In this way, factory obtains the means to settle a promise.

var promise = new Promise(function (resolve, reject) {
  // ..
});

Calling resolve(x)

  1. If x is a non-thenable,
    1. If promise is pending, promise must be fulfilled with x as its fulfillment value.
    2. If promise is settled, nothing happens (in particular, no exception may be thrown).
  2. If x is a thenable, promise must attempt to adopt the state of x (see Promises/A+ spec).

Calling reject(reason)

  1. If promise is pending, promise must be rejected with reason as its rejection reason.
  2. If 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:

var promise = Promise.from(thenable);
  1. If thenable is not an object or function, throw a TypeError.
  2. If thenable does not have a property then that is a function, throw a TypeError.
  3. Otherwise, return the result of new Promise(thenable.then).

Notes

  1. In practical terms, an implementation must use a mechanism such as setTimeout, setImmediate, or process.nextTick to ensure that factory is not called in the same turn of the event loop as the call to the promise constructor. Note that if factory throws an exception, it will necessarily be uncatchable and not interfere with any surrounding code, since the execution stack is empty.
@domenic
Copy link
Member Author

domenic commented Feb 10, 2013

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.

@domenic
Copy link
Member Author

domenic commented Feb 10, 2013

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.

@domenic
Copy link
Member Author

domenic commented Feb 10, 2013

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant