Re: Exceptions in event listeners triggered by dispatchEvent().

On Mon, Jun 3, 2013 at 6:33 PM, John Barton <johnjbarton@google.com> wrote:

> This is a widely-used API, it's years too late to change this.
>>
>
> I understand this limitation and how hard it may be to know if the current
> behavior is the only one which can work.
>

It's not hard.  I've written plenty of code myself that would break
completely if it didn't dispatch the event synchronously.  This is a basic
pattern:

function doSomething(element) {
    var e = new Event("someEvent", { cancelable: true });

    // Dispatch the event.  If any listener calls stopPropagation, return
without doing anything else.
    if(!element.dispatchEvent(e))
        return;

    // Nobody cancelled the event, so do our default action.
    doSomethingElse(element);
}


> Sorry, this is not at all what I had in mind. Rather:
>    targetElement.dispatch(event); // all listeners run on future turns, we
> continue, no blocking, no join.
>

That doesn't give you access to the resulting state of the event, which is
a key part of the event model.


> Consider the following code, assuming one of the listeners throws:
> ----
>    try {
>      targetElement.dispatchEvent(evt);
>    } catch(exc) {
>      console.log("A listener had a error");
>      return;
>    }
>    goOnToGlory();
> ----
>
> How can a developer know that the catch block can never be executed and
> yet exceptions in handlers are reported as uncaught? The only other
> experience that I know about which accounts with these two facts is that
> dispatchEvent() schedules listener executions on another event turn.  But
> it doesn't, it's just another wacko Web behavior we have to look up and
> memorize.
>

The same ways that you understand the details of any API: documentation and
experience.  I don't think "if a function doesn't propagate exceptions,
then it's asynchronous" is a good goal--that's even wackier.

Making APIs asynchronous makes them much more cumbersome to use.  Making
APIs asynchronous for something like this is introducing a very big
inconvenience to try to solve a very minor one.  (And adding a second
asynchronous API alongside dispatchEvent doesn't solve anything--now you
have two similar-looking functions with different behavior, which isn't
likely to make anything clearer.)

-- 
Glenn Maynard

Received on Tuesday, 4 June 2013 00:10:24 UTC