- From: Jonas Sicking <jonas@sicking.cc>
- Date: Thu, 14 Mar 2013 01:36:50 -0700
- To: Bjoern Hoehrmann <derhoermi@gmx.net>
- Cc: Anne van Kesteren <annevk@annevk.nl>, Yehuda Katz <wycats@gmail.com>, www-dom@w3.org, slightlyoff@google.com
On Thu, Mar 14, 2013 at 12:12 AM, Jonas Sicking <jonas@sicking.cc> wrote: > On Mar 13, 2013 10:04 AM, "Bjoern Hoehrmann" <derhoermi@gmx.net> wrote: >> >> * Jonas Sicking wrote: >> >The exact syntax here is of course to-be-determined, but the idea is >> >that it's the exact same syntax as the "on" function, except that it >> >doesn't take a handler-function argument. Instead a Future is returned >> >and this future is resolved (using the Event object) the first time >> >the corresponding "on" handler-function would have been called. >> > >> >One tricky issue is the exact timing of the call to the .then >> >function. It would be great if we could enable the resolver function >> >to do things like call .preventDefault on the event, but that might >> >require that the .then function is called synchronously which goes >> >against [1]. >> > >> >[1] https://github.com/slightlyoff/DOMFuture >> >> Could you elaborate on where you see the problem here? > > Currently [1] defines that a future is always resolved at the end of > the current microtask. So when you call resolver.accept it won't > synchronously call the callbacks registered through .then(). Nor is > the .state or .value changes synchronously. > > Instead these things happen at the end of the microtask. > > This works great for most events. For a "click" event fired in > response to the user clicking a link, we'd call resolver.accept to > resolve the Future. Since we're not currently in a microtask, that > means that we would immediately update the Future's state and start > calling the .then()-registered callbacks. > > Another way to look at it is that the implementation of .once() would > look something like: > > EventTarget.prototype.once = function(eventType, options) { > var self = this; > return new Future(function (resolver) { > self.on(eventType, options, function(event)) { > resolver.accept(event); > }); > }); > }; > > Here the returned Future would be resolved at the end of the > microtask, which means as soon as the event handler exits, but before > the next event handler runs. I.e. the Future would be resolved at the > same time as a normal event handler would be run. I.e. things work > great. > > However, if the event is dispatched synchronously, say for example the > loadstart event dispatched in response to a call to XHR.send(), or a > custom event dispatched manually using EventTarget.dispatchEvent(), > things don't work as well. > > In this case the entire event dispatch, and calling all event > handlers, happens as part of a single microtask. So "the end of the > microtask" isn't reached until after all of the event dispatched has > happened. > > We could solve this by defining that the EventTarget code calls some > internal hidden function on the resolver which synchronously resolves > the Future. But that doesn't seem like a good solution. > > Ideally I think we'd never fire events synchronously, but rather at > the end of microtasks or asynchronously, in which case this wouldn't > be a problem. But that ship sailed many years ago. > > I suspect this is something that needs to be fixed in the Futures API > and not in the event dispatch code. I filed https://github.com/slightlyoff/DOMFuture/issues/47 / Jonas
Received on Thursday, 14 March 2013 08:37:48 UTC