Where'd Promise#done go?

Ron Buckton rbuckton at chronicles.org
Tue Jun 18 21:55:47 PDT 2013


I've often looked at Promise#then() as sugar over Promise#done() for something like:

```js
Promise.prototype.then = function(resolve, reject) {
  return new Promise(resolver => {
    this.done(
      value => {
        try {
          resolver.resolve(resolve ? resolve(value) : value);
        }
        catch (e) {
          resolver.reject(e);
        }
      },
      err => {
        try {
          resolver.resolve(reject ? reject(value) : value);
        }
        catch (e) {
          resolver.reject(e);
        }
      });
  });
}
```

Promise#done() doesn't have the overhead that Promie#then does (allocating a new chained Promise), so it is more efficient if you don't need to chain. It feels easier to be more explicit with done then without, since to polyfill done requires calling something like setImmediate to raise the error to the engine/window.onerror, since throwing it in the reject handler would just result in a new rejected Promise.

If we had an 'await' keyword I might find the need for done to be less important, as it would be easy to write "await p" to bubble the exception to user code. Although, 'await' would also be more efficient with 'done' rather than 'then'.

If Promise#done is out, a polyfill could just have an array of unhandled exceptions that could be analyzed programmatically in user code or via the console.

Sent from Windows Mail

From: Mark S. Miller
Sent: ?Tuesday?, ?June? ?18?, ?2013 ?8?:?14? ?PM
To: Domenic Denicola
Cc: es-discuss

On Tue, Jun 18, 2013 at 8:11 PM, Domenic Denicola <domenic at domenicdenicola.com<mailto:domenic at domenicdenicola.com>> wrote:
From: Mark S. Miller [mailto:erights at google.com<mailto:erights at google.com>]

> I don't understand this. I am onboard with `console.unhandledRejection`/`console.rejectionHandled` and all that for better logging, and with using WeakRef notification to improve the logging yet further. But I don't see how any of this can substitute for the need that .done() serves. I think we will still need .done() in ES7 promises.

While I think I see what you're getting at,

What do you think I'm getting at? ;)


 let me play devil's advocate for a bit to draw this out more clearly. Using the sample code from https://github.com/promises-aplus/unhandled-rejections-spec/issues/1:

```js
var rejectPromise;
var promise = new Promise((resolve, reject) => rejectPromise = reject);

promise.then(() => console.log("I only attached a handler for fulfillment"));
// All is OK (A)

rejectPromise(promise, new Error("who handles me?"));
// Nobody sees the error! Oh no, maybe we should crash here? (B)

setTimeout(function () {
    promise.then(undefined, (err) =>console.error("I got it!", err));
    // But if we crashed there, then how would this code ever get run? (C)
}, 5000);
```

Using a `done`-less promise implementation with a unhandled rejections console, we have the flow that:

1. At line (A), all is fine, and the unhandled rejections console is empty.
2. At line (B), the unhandled rejections console contains `Errror: "who handles me?"`. This remains true for the next five seconds.
3. At line (C), after five seconds have passed, the unhandled rejections console becomes yet again empty.

This seems to neatly solve the problem without `done`, at least in my devil's-advocate world. Where's the problem? :)



--
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130619/c035cdd9/attachment-0001.html>


More information about the es-discuss mailing list