W3C home > Mailing lists > Public > whatwg@whatwg.org > October 2014

Re: [whatwg] Notifications: making requestPermission() return a promise

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Wed, 1 Oct 2014 11:34:04 -0400
Message-ID: <CAAWBYDCmfoxVPgs+Xrk+0mLHh-1dQzu9K-Tt2PDZTTdRF1wUBw@mail.gmail.com>
To: Anne van Kesteren <annevk@annevk.nl>
Cc: WHATWG <whatwg@whatwg.org>, Jake Archibald <jaffathecake@gmail.com>, Jonas Sicking <jonas@sicking.cc>, Andrew Wilson <atwilson@google.com>, Peter Beverloo <beverloo@google.com>
On Wed, Oct 1, 2014 at 9:34 AM, Anne van Kesteren <annevk@annevk.nl> wrote:
> On Wed, Oct 1, 2014 at 3:21 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>> And I wouldn't expect someone loading a FontFace synchronously to use
>> try/catch to deal with loading errors, either, because that's super
>> obnoxious.  Failure, though, is a standard rejection reason - it maps
>> to the use of "onerror" events.
>>
>> Without it, the promise algebra functions become far less useful, and
>> you have to type-test the fulfillment value to see if it's actually
>> the value you want, or some sort of proxy that communicates failure.
>
> Once we have async/await syntax the synchronous version is what you
> get. I would not want try/catch for requestPermission() there. As far
> as I know promises are just like functions in that regard, you only
> want to reject/throw if you want to force try/catch on the user.

Yeah, this is a mismatch of expectations based on how you use it.

If you're using Promises, and the promise algebra like .all() or
.race(), you expect only "success" to result in fulfillment; "failure"
should reject, so you can specialize your code paths properly and have
the algebra work well.  I want to be able to use Promise.all() on
several permission requests to tell if I get them all; if they always
fulfill, Promise.all() becomes solely a synchronization primitive, not
a useful value algebra operation.

If you're using async/await to hide the asynchrony, you only want
error situations to throw, because dealing with throwing is really
annoying.

This is actually kinda terrible.  Promises make it *really easy* to
deal with rejections *later*, letting you execute a bunch of code on
the success path and only at the end saying "Oh, did something along
the line fail? Let me take care of that.".  Promise is basically an
async Maybe monad, which is great, because Maybe is useful for
*exactly the scenario I just outlined*.

Changing things so that you have to go back to wrapping all your code
in try/catch (and not just the one call - if you're chaining promises,
they *all* have to be wrapped) is kinda terrible, and distorts the
ergonomics of the system.  What was once great, when done directly
with Promises, is now terrible, when done with async/await; you're
forced to pay for that convenience!

I think we should develop Promises in a way that exploits their
ergonomics properly, and then rethink async/await a bit to make it
match those ergonomics, rather than fighting them.

~TJ
Received on Wednesday, 1 October 2014 15:34:53 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 17:00:24 UTC