Where'd Promise#done go?

Mark S. Miller erights at google.com
Wed Jun 19 07:01:42 PDT 2013


On Wed, Jun 19, 2013 at 3:28 AM, Alex Russell <slightlyoff at gmail.com> wrote:

> On Wednesday, June 19, 2013, Ron Buckton wrote:
>
>>  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.
>>
>
> That is my only latent argument for #done(), and one that I think I agree
> with Luke to re-visit at some later date. We can always add.
>
> What was less clear is that there's any real problem with error handling:
> polyfills can (should?) keep lists of unhandled promises and make them
> available to tools while we wait for devtools to surface the list. The
> concerns here with direct logging seem, to me, to be premature.
>

Regarding prematurity, I said "I think we will still need .done() in ES7
promises." I do not think this is something that DOMPromises need to
address prior to the careful ES7 promise work still in front of us. Since,
as you and Luke say, "We can always add", DOMPromises only needs be
approximately the minimum we need quick agreement on, so that we can add
the rest of what's needed in the ES7 process. This they seem to be, which
is great.




>
>
>>  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> wrote:
>>
>>> From: Mark S. Miller [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
>>
>


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


More information about the es-discuss mailing list