domenic/promises-unwrapping

Handling of promises returned from onRejected

lukehoban opened this issue · 1 comments

The spec currently doesn't appear to handle promises returned from onRejected in the way that most promises implementations/specs i'm familiar with do (including Promises/A+, WinJS and the previous DOM Futures spec).

xhr("example.com/a")
  .then(req => xhr("example.com/b"), err => xhr("example.com/default"))
  .then(req => console.log("completed with:" + req.responseText));

In this example, both the success and failure branches of the first then return promises. So the final promise should resolve only when the selected branch's promise is resolved/rejected.

By the current spec, I believe if the error branch is followed, the final promise will resolve with a Promise instead of a request object and will not wait on that promise completing.

Supporting promises returned from error handlers is useful for, among other things, error recovery - automatic retry with backoff on failure, etc. It also makes the API more consistent/predictable.

Was this an intentional change (if so, why?), or am I reading the spec wrong?

I believe you are reading the spec wrong. A rejected promise will update any promises returned from its then method via the spec-internal method UpdateDerivedFromReason, which calls CallHandler(returnedPromiseFromThen, onRejectedPassedToThen, reason). CallHandler accounts for any return value by calling Resolve(returnedPromiseFromThen, theReturnValue), and of course resolve does the usual resolve action of if-promise-follow, if-value-fulfill.

You can verify this by the fact that all the Promises/A+ tests pass, and the implementation they are tested against is basically a verbatim translation of the spec.