Better event listeners

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
56 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Anne van Kesteren-4
On Tue, Feb 12, 2013 at 2:23 PM, Glenn Maynard <[hidden email]> wrote:
> It doesn't work completely differently.  It works exactly the same.
> addEventListener("click", func, true) would be exactly equivalent to
> addEventListener("click", func, {capture: true}).

Yes, but it would also return an object (for which it's not at all
clear that's web compatible). And I think if the preferred API is
going to support event delegation we should also by default ignore
bubbles.


--
http://annevankesteren.nl/

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Glenn Maynard
On Tue, Feb 12, 2013 at 8:33 AM, Anne van Kesteren <[hidden email]> wrote:
On Tue, Feb 12, 2013 at 2:23 PM, Glenn Maynard <[hidden email]> wrote:
> It doesn't work completely differently.  It works exactly the same.
> addEventListener("click", func, true) would be exactly equivalent to
> addEventListener("click", func, {capture: true}).

Yes, but it would also return an object (for which it's not at all
clear that's web compatible). And I think if the preferred API is
going to support event delegation we should also by default ignore
bubbles.

No, addEventListener would always return the object, not just when it takes an object.  That's just adding an orthogonal feature to the method.  (Whether there's code out there somehow depending on addEventListener's lack of return value is a separate question; I don't know, of course.)

Ignoring bubbles by default makes me a little nervous, since it's a subtle difference between very similar APIs which people less experienced with DOM events won't necessarily understand.  Either way, though, having a different default doesn't seem like a good reason to have a completely separate API.

--
Glenn Maynard

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Sean Hogan
In reply to this post by Anne van Kesteren-4
On 5/01/13 11:26 PM, Anne van Kesteren wrote:

> We discussed this a long time ago. Lets try again. I think ideally we
> introduce something like http://api.jquery.com/on/ Lets not focus on
> the API for now, but on what we want to accomplish.
>
> Type and callback are the basics. Selector-based filtering of
> event.currentTarget should be there, but optional. I'm not sure about
> the data feature, Yehuda?
>
> Should we make all events bubble for the purposes of this new
> registration mechanism? I actually thought Jonas said jQuery did that
> at some point, but the jQuery documentation does not suggest it does.
>
> Should we have event-data-based filtering? E.g. developers could
> register to only get key events for the WASD keys. Optimization for
> developers could be that they get to have one callback per key,
> optimization for browsers and speed of the application would be that
> less events need to be processed ideally leading to a better user
> experience.
>
> It seems capture-listeners are not needed. At least for now.
>
>

Some use cases - mostly related to event-delegation:

1. pushState assisted navigation
This might require handling click events on all hyperlinks <a
href="..."> in the page.
Instead of attaching handlers to all <a href> in the page - most of
which will never be clicked - I would like to register one handler on
the document and use event-delegation.

A hyperlink might contain other elements meaning that the <a> is never
the `target` of the click. e.g.
     <a href="/index.html"><span>Home</span></a>

Additionally, browsers have different behaviors for clicks that aren't
generated by the left button, or clicks that occur while a modifier key
(metaKey, ctrlKey, altKey) is depressed. I don't want to handle a click
in those cases.
I'd like my handler to only be called for an event matching:

     {
         type: 'click',
         element: 'a[href]',
         eventPhase: "bubbling",
         button: 'left',
         metaKey: false,
         ctrlKey: false,
         altKey: false,
         shiftKey: false
     }

I don't want my handler called until the event bubbles up to the
document - this will allow other handlers to prevent my handler if
appropriate. Naturally I want to know which element matched the selector.

Alternatively, if the handler is triggered as the event bubbles thru the
<a href>, I would extend the event object with fields like

     {
         url: event.currentTarget.href,
         replace: false,
         hyperlink: event.currentTarget
     }

Another handler on the document would take care of pushState (if the
event hasn't been stopped or prevented).


2. Sortable table
This might involve handling all click events on <th> that are inside the
<thead> of the table.
Again, the <th> could easily contain other elements which mean it is not
the `target` of the event.
I would prefer my handler to be called as the event bubbles through the
<th>. My handler could be prevented by a capturing event handler.
I'd like my handler to only be called for click events on descendants of
the <table> that match

     {
         type: 'click',
         element: 'thead th',
         eventPhase: "bubbling",
         button: 'left',
         metaKey: false,
         ctrlKey: false,
         altKey: false,
         shiftKey: false
     }


3. Tree
A tree could be a base pattern for a directory, document-map, emulated
<select>.
The tree might be collapsible or sub-lists might only appear on
mouseenter. It might have dynamically generated or AJAX'd content.
It is implemented as a list of lists, perhaps like this:

     <div class="tree">
         <label>My Tree</label>
         <ul>
             <li>1
                 <ul>
                     <li>1.1</li>
                     <li>1.2</li>
                     ...
                 </ul>
             </li>
             <li>2
                 <ul>
                     <li>2.1</li>
                     ...
                 </ul>
             </li>
             ...
         </ul>
     </div>

I want to detect UI events on any <li> in the tree, but I don't want to
add listeners up front because some items might not be present, and
especially since most of them won't ever be interacted with.

The tree might have an *active* item, which can be set by a cick. My
click handler should only be called for descendants of the <div
class="tree"> that match

     {
         type: 'click',
         element: 'li',
         eventPhase: "bubbling",
         button: 'left',
         metaKey: false,
         ctrlKey: false,
         altKey: false,
         shiftKey: false
     }

I need my handler to be called as the event bubbles through <li> so that
I can prevent ancestor <li>'s from also handling it.


Apologies for the verbosity.  I'll add some analysis in another email.
Sean


Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Glenn Maynard
On Sun, Feb 17, 2013 at 9:22 PM, Sean Hogan <[hidden email]> wrote:
It seems capture-listeners are not needed. At least for now.

Some use cases - mostly related to event-delegation:

Not to say capture isn't useful, but these mostly aren't actually use cases for capture, because you shouldn't use capture for these things.  Instead, you should use normal bubbling listeners.

1. pushState assisted navigation
This might require handling click events on all hyperlinks <a href="..."> in the page.
Instead of attaching handlers to all <a href> in the page - most of which will never be clicked - I would like to register one handler on the document and use event-delegation.

If you mean having links that push script-local state, don't intercept every <a> press and insert a script that calls pushState.  Just use hashes and onpopstate; see http://zewt.org/~glenn/hash-navigation.html for an example.  Intercepting clicks and using pushState is a lot of unnecessary work, and is a lot harder to make work in general (eg. when users right-click and select "copy link URL" or "open in new tab", both of which work perfectly with this example).

That said, if you do want to delegate listeners, you should use bubbling listeners, not capturing listeners.  For example, that would break <a href="..." onclick="return false;">, since you'd act on the click before the anchor's event listener has a chance to cancel it.  One thing the API we're discussing aims to fix this, by allowing event handlers to ignore the bubbles flag.
 
A hyperlink might contain other elements meaning that the <a> is never the `target` of the click. e.g.
    <a href="/index.html"><span>Home</span></a>

Event delegation doesn't depend on the target of the link.  Put a bubbling event listener on window (or document, or another logical container), and search up the tree (starting at event.target) for an element matching the CSS selector "a".  For an example, see http://zewt.org/~glenn/delegation-example.html.  (Making this simpler is something this API aims to do.  Element.closest() is also something that really needs to be added to the selector API, though.)
 
Additionally, browsers have different behaviors for clicks that aren't generated by the left button, or clicks that occur while a modifier key (metaKey, ctrlKey, altKey) is depressed. I don't want to handle a click in those cases.

As long as you're listening to onclick (and not eg. onmousedown), you shouldn't need to do anything special here.
 
Again, the <th> could easily contain other elements which mean it is not the `target` of the event.
I would prefer my handler to be called as the event bubbles through the <th>.

This has been suggested recently on https://www.w3.org/Bugs/Public/show_bug.cgi?id=16491, though it's not yet clear whether this is a good idea in practice.

--
Glenn Maynard

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Sean Hogan
On 18/02/13 3:11 PM, Glenn Maynard wrote:
On Sun, Feb 17, 2013 at 9:22 PM, Sean Hogan <[hidden email]> wrote:
It seems capture-listeners are not needed. At least for now.

Some use cases - mostly related to event-delegation:

Not to say capture isn't useful, but these mostly aren't actually use cases for capture, because you shouldn't use capture for these things.  Instead, you should use normal bubbling listeners.

I wasn't giving use cases for capture-listeners - I was responding to the email to which I replied, which just happened to end with the line you have extracted.


Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Jonas Sicking-2
In reply to this post by Anne van Kesteren-4
On Sat, Jan 5, 2013 at 4:26 AM, Anne van Kesteren <[hidden email]> wrote:

> We discussed this a long time ago. Lets try again. I think ideally we
> introduce something like http://api.jquery.com/on/ Lets not focus on
> the API for now, but on what we want to accomplish.
>
> Type and callback are the basics. Selector-based filtering of
> event.currentTarget should be there, but optional. I'm not sure about
> the data feature, Yehuda?
>
> Should we make all events bubble for the purposes of this new
> registration mechanism? I actually thought Jonas said jQuery did that
> at some point, but the jQuery documentation does not suggest it does.
>
> Should we have event-data-based filtering? E.g. developers could
> register to only get key events for the WASD keys. Optimization for
> developers could be that they get to have one callback per key,
> optimization for browsers and speed of the application would be that
> less events need to be processed ideally leading to a better user
> experience.
>
> It seems capture-listeners are not needed. At least for now.

Something else that occurred to me might be very nice would be able to
get a Future [1] representing the next time a particular event has
fired. I.e. something like

myelement.once("click").then(function(event) { ... });

and

myeleemnt.once("click", { selector: "div > a", phase: "bubble" }).then(...);

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

/ Jonas

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Bjoern Hoehrmann
* 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? If you can't get
your code called at the same time your .addEventListener code would be
called, then such a feature would seem worse than useless. The primary
utility in having "futures everywhere" would be to support higher-level
protocols that use them, like <http://taskjs.org/>, or simply something
like, using your syntax,

  var event = await elem.once("event");
  ...

which should be essentially equivalent to

  elem.addEventListener("event", function(event) {
    ...
  }, false);

My own http://lists.w3.org/Archives/Public/www-archive/2008Jul/0009.html
ensures this by resuming execution from the .addEventListener callback.
--
Björn Höhrmann · mailto:[hidden email] · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/ 

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Jonas Sicking-2
On Mar 13, 2013 10:04 AM, "Bjoern Hoehrmann" <[hidden email]> 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.

/ Jonas

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Jonas Sicking-2
On Thu, Mar 14, 2013 at 12:12 AM, Jonas Sicking <[hidden email]> wrote:

> On Mar 13, 2013 10:04 AM, "Bjoern Hoehrmann" <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

David Bruant-5
In reply to this post by Jonas Sicking-2
Le 13/03/2013 16:47, Jonas Sicking a écrit :
> 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].
I consider that the DOM event model is absurdly broken. Namely, all
listeners being called synchronously on .dispatchEvent is a bad idea.
I don't think retrofitting Futures into that model is a good idea. Maybe
a better idea would be to add a way for event handlers to be .dispatched
asynchronously. That would fit in the Future model, but even then I'm
not sure it's a good idea.

I see Futures as a convenience (or "design pattern" maybe) written on
top of events (the general idea of events, not necessarily the ones
defined in the DOM). An object having mutually exclusive success/error
events where at most one will be fired is pretty common and Futures
makes an idiom out of this recurring pattern.
But not all events follow this pattern. "readystatechange" is meant to
be fired several times, for instance.

If people want to make a future out of an upcoming existing event, they
can do so in a few lines (as expressed here [1]). Maybe it will be a
very common pattern for futures, but it's not certain. Maybe people will
use that only for a handful of other events and we'll see a different
pattern emerge.
I'd be more in favor of shipping minimalistic futures, see how people
use them and add hooks to DOM events after having a better understanding
of how people use events in combination with Futures, but not before.

David

[1] https://github.com/slightlyoff/DOMFuture/issues/34#issuecomment-14236676

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Olli Pettay
On 03/14/2013 11:48 AM, David Bruant wrote:
> Le 13/03/2013 16:47, Jonas Sicking a écrit :
>> 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].
> I consider that the DOM event model is absurdly broken. Namely, all listeners being called synchronously on .dispatchEvent is a bad idea.
> I don't think retrofitting Futures into that model is a good idea. Maybe a better idea would be to add a way for event handlers to be .dispatched
> asynchronously. That would fit in the Future model, but even then I'm not sure it's a good idea.
I don't think there are too many use cases for async listeners and using setTimeout() is easy.

>
> I see Futures as a convenience (or "design pattern" maybe) written on top of events (the general idea of events, not necessarily the ones defined in
> the DOM). An object having mutually exclusive success/error events where at most one will be fired is pretty common and Futures makes an idiom out of
> this recurring pattern.
> But not all events follow this pattern. "readystatechange" is meant to be fired several times, for instance.
>


> If people want to make a future out of an upcoming existing event, they can do so in a few lines (as expressed here [1]). Maybe it will be a very
> common pattern for futures, but it's not certain.
agree

> Maybe people will use that only for a handful of other events and we'll see a different pattern emerge.
> I'd be more in favor of shipping minimalistic futures, see how people use them and add hooks to DOM events after having a better understanding of how
> people use events in combination with Futures, but not before.
and agree even more.



-Olli

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Jonas Sicking-2
In reply to this post by David Bruant-5
On Thu, Mar 14, 2013 at 2:48 AM, David Bruant <[hidden email]> wrote:

> Le 13/03/2013 16:47, Jonas Sicking a écrit :
>
>> 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].
>
> I consider that the DOM event model is absurdly broken. Namely, all
> listeners being called synchronously on .dispatchEvent is a bad idea.
> I don't think retrofitting Futures into that model is a good idea. Maybe a
> better idea would be to add a way for event handlers to be .dispatched
> asynchronously. That would fit in the Future model, but even then I'm not
> sure it's a good idea.

Adding something like
interface EventTarget {
  ...
  Future<boolean> dispatchEventAtEndOfMicrotask(Event event);
}

is certainly doable, but unfortunately wouldn't fix the problem. We'd
still have the case that *some* events are fired synchronously.

We could of course say that any events that are fired synchronously
doesn't resolve the .once Futures. Or that they would trigger, but
they wouldn't have the ability to call .preventDefault() etc. Either
of these solutions seem very broken though.

/ Jonas

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

David Bruant-5
In reply to this post by David Bruant-5
[cc'ing Rick Waldron. For context start of the relevant part of the
thread at http://lists.w3.org/Archives/Public/www-dom/2013JanMar/0202.html ]

Le 14/03/2013 10:48, David Bruant a écrit :

> Le 13/03/2013 16:47, Jonas Sicking a écrit :
>> 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].
> Maybe people will use that only for a handful of other events and
> we'll see a different pattern emerge.
> I'd be more in favor of shipping minimalistic futures, see how people
> use them and add hooks to DOM events after having a better
> understanding of how people use events in combination with Futures,
> but not before.
I've spent some time looking at jQuery and since they've added Deferred
[1] (a promise-family mechanism), I haven't found evidence that they
turn an event to a deferred.
I'll let jQuery experts Yehuda and Rick tell me if I'm wrong.
I also haven't found sign of other libraries doing that either (people
knowing about other libraries can jump in here)

Assuming I am not mistaken on how jQuery Deferred and events don't
interact, I take that as a signal that it might not be something people
use and probably even need.

David

[1] http://api.jquery.com/jQuery.Deferred/

Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Brandon Wallace
As an author, I very rarely need to subscribe to a single occurrence of an event.  The vastly more common case is to subscribe to a stream of events until some condition is met, then unsubscribe from the stream.

Since a future represents a single occurrence of an event, it can really only be used in the rare case, but not in the common multi-occurrence case.  But then I would have to choose to use a different API (Futures) for this rare case.  Why would I do that, when I could instead use the common streaming API and just unsubscribe when the event occurs?

RxJs has bindings to map events to observables, which is a much more natural fit since Rx observables represent a stream of events.  I use this mapping all the time.  In the rare case that I only want a single occurrence of the event, I just append  ".take(1)" to the end of the observable.

This is why I, at least, am not interested in the ability to map events to futures.

--
Brandon

On Mar 16, 2013, at 8:49 AM, David Bruant <[hidden email]> wrote:

> [cc'ing Rick Waldron. For context start of the relevant part of the thread at http://lists.w3.org/Archives/Public/www-dom/2013JanMar/0202.html ]
>
> Le 14/03/2013 10:48, David Bruant a écrit :
>> Le 13/03/2013 16:47, Jonas Sicking a écrit :
>>> 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].
>> Maybe people will use that only for a handful of other events and we'll see a different pattern emerge.
>> I'd be more in favor of shipping minimalistic futures, see how people use them and add hooks to DOM events after having a better understanding of how people use events in combination with Futures, but not before.
> I've spent some time looking at jQuery and since they've added Deferred [1] (a promise-family mechanism), I haven't found evidence that they turn an event to a deferred.
> I'll let jQuery experts Yehuda and Rick tell me if I'm wrong.
> I also haven't found sign of other libraries doing that either (people knowing about other libraries can jump in here)
>
> Assuming I am not mistaken on how jQuery Deferred and events don't interact, I take that as a signal that it might not be something people use and probably even need.
>
> David
>
> [1] http://api.jquery.com/jQuery.Deferred/
>

Reply | Threaded
Open this post in threaded view
|

RE: Better event listeners

Francois Remy-3
In reply to this post by David Bruant-5
> Assuming I am not mistaken on how jQuery Deferred and events don't
> interact, I take that as a signal that it might not be something people
> use and probably even need.

I'm not going to enter the debate, but event debouncing has become a pretty important problem nowadays, particularly for sensitive synchronous events like 'onscroll', 'onmousemove' and mutation events.

Could Future(s) help solve this problem in an elegant way? I don't know, but the approach seems,worth investivating.

(approach: create a Future for multiple events that should trigger a relayout, once one of them happen, your handler is queued for execution and removed from the listeners, when your handler is called you have the opportunity to 'reset' the Future to reregister to the events)

The advantage is that you debounce at the same time multiple events, any kind of them (DOM events but also any kind of future-generator).    
Reply | Threaded
Open this post in threaded view
|

Re: Better event listeners

Mounir Lamouri-3
In reply to this post by Brandon Wallace
On 16/03/13 14:20, [hidden email] wrote:
> As an author, I very rarely need to subscribe to a single occurrence of an event.  The vastly more common case is to subscribe to a stream of events until some condition is met, then unsubscribe from the stream.
>
> Since a future represents a single occurrence of an event, it can really only be used in the rare case, but not in the common multi-occurrence case.  But then I would have to choose to use a different API (Futures) for this rare case.  Why would I do that, when I could instead use the common streaming API and just unsubscribe when the event occurs?

I agree with Brandon, given that Future can only apply with something
like .once(), I doubt it is really useful to try to include Future here
because part of the API would be using the traditional callbacks and
another part would be using Future. The inconsistency doesn't seem to be
worth it.

--
Mounir

123