Experimental implementation of Object.observe & JS Utility library now available

John J Barton johnjbarton at johnjbarton.com
Mon Aug 20 20:57:16 PDT 2012


On Sun, Aug 19, 2012 at 3:31 PM, Rafael Weinstein <rafaelw at chromium.org>wrote:

> On Sun, Aug 19, 2012 at 11:25 AM, John J Barton
> <johnjbarton at johnjbarton.com> wrote:
> >
> >
> > On Fri, Aug 17, 2012 at 9:49 PM, Rafael Weinstein <rafaelw at chromium.org>
> > wrote:
> >>
> >> >> A synchronous observation mechanism provides an attacker too many
> >> >> opportunities for a plan interference attack. If you'll recall, an
> >> >> earlier
> >> >> synchronous proposal died for this reason.
> >>
> >> That is an excellent reason. I have two others:
> >>
> >> 1) It's a terrible design pattern to encourage. Webdevs will
> >> absolutely use it and learn the hard way, just like we did with
> >> Mutation Events that it works fine when we start, but down the road
> >> lies nothing but pain and suffering.
> >>
> >> 2) Synchronous doesn't actually exist -- it's a false option.
> >>
> >> To explain: When people talk about "synchronous" what they expect is
> >> that they will be notified concurrent with the event happening (this
> >> *is happening*). The expectation is that when they are invoked they
> >> are observing the world as the event is describing.
> >>
> >> This is the appeal of synchronous delivery. Here's the rub: unless you
> >> plan to only allow a single observer per object, then you have to pick
> >> someone to go first. And unless you plan to prevent that person from
> >> further mutating the object, the next guy to be called may not observe
> >> the world in the state suggested by the "synchronous" call.
> >>
> >> In fact, an arbitrary number of mutations can always have occurred by
> >> the time any given observer is called, so it's just dishonest API
> >> which pretends that a single thing has happened. The correct thing is
> >> to inform each observer what *set* of things has happened.
> >>
> >> So the only questions are:
> >>
> >> 1) Do you mislead the consumer with API which suggests that only one
> >> thing will has happened
> >> 2) If not, when do you deliver the set of things: immediately after
> >> the mutation occurs, at the end of the turn or ask the UA to schedule
> >> a future task.
> >>
> >> Referring back to my reason (1) This question was debated extensively
> >> with DOM Mutation Observers and unanimously decided that the end of
> >> the turn was the only good solution. "immediately" puts all code in
> >> danger of having its runtime assumptions invalidated after every
> >> operation which mutates objects and "future task" is far too late to
> >> be useful for most almost all use cases.
> >
> >
> >
> > I can understand how batched changes and end-of-turn asynchronous calls
> are
> > a good match.  The development model is now "here are the changes from
> this
> > turn" rather than "here is a change".
> >
> > But I don't understand how end-of-turn asynchronous calls helps with the
> > multiple independent listeners problem. If a listener can mutate the DOM,
> > then change-listeners depend upon change-listeners. The relative timing
> of
> > the listener calls and the non-listener DOM mutations does not change
> that
> > dependency.
> >
> > And once change-listeners mutate the DOM then the API of "here are the
> > changes from this turn" again misleads the developer relying on it.
>
> Actually, this isn't quite right. It's "here are all the changes since
> the last time you were invoked". I.e. every observer is always
> delivered all changes to all entities it is observing up to the time
> that it is invoked. To be concrete, the following invariants always
> hold:
>
> A) When an observer is invoked, is it delivered a sequence of change
> records representing all changes to entities it is observing -- up to
> the time of its invocation.
> B) When an observer is invoked, it is free to mutate entities and do
> work without risk of being preempted by other observers being notified
> of changes it makes.
> C) Conversely, when an observer is invoked, no other script is below
> it on the stack.
> D) An observer will be delivered all changes to entities it is
> observing before the turn ends.
>
> These are true for both Object.observe() and for DOM Mutation Observers.
>
> In other words, any given observer can be blissfully ignorant of all
> other actors in the system. It is always delivered a full picture of
> what has happened in its world, it can act completely independently of
> other actors, and it will always get all of its changes before the
> turn ends.
>
> Does this address your concern?
>

Can we create a simple example that demonstrates the API advantage of
asynchronous events in the multiple observer case?

The example would need a DOM mutations (M1) and two handlers (H1 and H2)
and let's have H1 mutate the DOM (M2) in a way that H2 depends upon

Synchronous, H1 first:
   H1(M1) H2(M2) H2(M1)  <<< correct? or H2(M1, M2)?
Async, H1 first
   H1(M1) H2(M1)  H2(M2)

Sync H2 first:
   H2(M1) H1(M1) H2(M2)
Async
  H2(M1) H1(M1) H2(M2)

If I am understanding correctly (and did the example correctly ;-), then
the async model fires all handlers with 1st order DOM mutations, then fires
all handlers with mutations created by other handlers (possibly repeating).

In the sync model, 2nd order mutations-from-mutation-handlers have to be
delivered before we finish the first round.

If I'm understanding correctly then the async model is clearer.

jjb
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120820/4fda800c/attachment.html>


More information about the es-discuss mailing list