node.js allows same listener type with same handler multiple times ... but
it has `maxListeners` number which is kinda pointless if events are not
even tracked and can be duplicated.
node also has this thing that you can drop everything from an emitter even
if you don't own registered events which is, in my opinion, undesired,
specially when you pass around your own modules expecting them to react in
certain cases.
That said, node.js folks had to quickly define/decide what was needed and
that's what they came up with ... it worked until now but I think I've
never seen a module that really needed all that API (there are too many out
there though so I might be wrong)
Not having this in core means every implementation will differ somehow and
this is the annoying part ... there's no way to write code that is
compatible with both worlds or all libraries without "sniffing" the
surrounding environment.
Let's say my module would like to intercept some generic event and react
... no standard way to even know which was the fired event in node, since
no type is passed, no easy way to check for errors in DOM world.
Keep telling devs to create their own Emitter because of this and that
weird case that should probably not exist in first place, and here I
believe that DOM and DOM based libraries have more experience than node.js,
cannot benefit anyone in both worlds for something needed since the very
beginning in every organized asynchronous situation.
As example, I do like the `{handleEvent:function(evt){}}` concept and used
that a lot without needing to bind anything because the context is always
the expected one (unless handleEvent has been bound differently, of course)
... in node I need to be careful that no extra listeners are added but the
amount of garbage created per each Emitter usage and bound objects is not
considered a problem? This is just weird, as weird is the decision that
since it's hard to make it right we rather prefer anarchy around the topic
per each slightly different, who knows why, behavior ...
node.js could have simply followed DOM logic passing Event or instanceof
Error as single argument, there is massive fragmentation there already but
here there was my attempt to bring more harmony around events.
node.js guys are OK with that, I can cope with that too, but having 2
different models without any win in both environment does not look like the
right approach to me.
Anyway, I started saying I was not even expecting people considering a
change ... so it's OK.
Best Regards
On Wed, Jul 10, 2013 at 5:12 PM, Jeremy Martin <[email protected]> wrote:
> Once again, this problem goes beyond simply polluting the prototype (which
> is enough of an issue by itself). The semantics for Emitters are somewhat
> of an 80/20 thing: 80% of all emitters need some common behavior, but the
> remaining 20% is custom.
>
> Going back to Node.js, for instance: everything would be great with
> `emitter.on(...)`, `emitter.once(...)`, `emitter.off(...)`,
> `emitter.emit(...)`, etc.
>
> But now we need `emitter.listeners(event)`, `emitter.setMaxListeners(n)`,
> etc. So, we still end up with a custom EventEmitter that implements the
> additional node-specific stuff, but we have a new problem: how do we
> implement `emitter.listeners(event)`? Without an exposed
> `emitter._listeners` (or similar) mapping, we're hosed. So do we
> monkey-patch the listener (de)registration methods? Yada yada, you get the
> point.
>
> The same problem exists with DOM events and most likely in any other
> non-trivial Emitter scenario. As I see it, it simply isn't practical at
> this level. The pollution issue goes far beyond 4 or 5 or even 10 new
> properties/methods if it's going to be robust enough to handle the
> already-common use cases, and if anything is missed developers will still
> be forced to sub-class it anyway (which is the only hassle that might've
> been worth avoiding in the first place).
>
> Alternatively, as Rick said, we could simply have:
>
> class Foo extends Emitter {}
> // or
> class Foo extends EventEmitter {}
> // or
> class Foo extends EddyEmitter {}
> // etc.
>
> This, IMO, is *far* more favorable and *far* less obtrusive (and already
> in the works).
>
> On Wed, Jul 10, 2013 at 7:27 PM, Andrea Giammarchi <
> [email protected]> wrote:
>
>> false.hasOwnProperty('whatever');
>> 1.0.isPrototypeOf({whate:'ver'});
>> 'string'.propertyIsEnumerable('whatever')
>>
>> these are already examples of an over-polluted prototype with methods
>> nobody uses ... I thought 4 extra methods everyone is using same way except
>> for Rick that honorees Tesla in this day would not hurt much but once
>> again, my point is that it's really about the time to put some standard
>> mechanism to deal with events in ES code.
>>
>> The fact Object.observe is already accepting a handler with an argument
>> which is fired as an event smells to me ... I'd rather define upfront a
>> common definition of handlers then propose any extra method based on them
>> ;-)
>>
>> Best Regards
>>
>>
>>
>> On Wed, Jul 10, 2013 at 4:04 PM, K. Gadd <[email protected]> wrote:
>>
>>> I think at this point we have a long history of language designs where
>>> random stuff has been tacked onto the core base class (i.e. Object) that
>>> really shouldn't have gone there - hashCode/toString in Java/C#, etc - such
>>> that any proposal to put something on Object instances deserves extreme
>>> skepticism. Static methods on Object aren't nearly so bad.
>>>
>>> In this case, the problem being solved can almost certainly be solved
>>> through composition or some other design mechanism. Bolting it onto every
>>> instance of Object, even if the only universally paid cost is a reserved
>>> name on the prototype, is simply not the right solution unless the
>>> downsides of other approaches are intolerable. Which they aren't.
>>>
>>> In practice a lot of these use cases call for event subscription and
>>> broadcasting to occur through a separate coordinator ('event bus') object
>>> and not through the object in question, anyway. This addresses a bunch of
>>> reference cycle problems that are caused when you subscribe directly to an
>>> object. You don't need to look much further than the DOM for examples...
>>>
>>>
>>> On Wed, Jul 10, 2013 at 3:57 PM, Rick Waldron <[email protected]>wrote:
>>>
>>>> I don't want any of this on my Object objects. Not all objects
>>>> represent something that can or should emit/publish/trigger/broadcast.
>>>>
>>>> For example...
>>>>
>>>> class Light {
>>>> constructor() {
>>>> // initialize Light control instance
>>>> }
>>>> on() {
>>>> // send bits to turn Light on
>>>> }
>>>> off() {
>>>> // send bits to turn Light off
>>>> }
>>>> }
>>>>
>>>>
>>>> So what happens now? All of my Led instances have emit, trigger, once
>>>> and boundTo methods that are actually useless now. No thanks. I also don't
>>>> want Object.prototype.* and Object.* to suffer the same way that the
>>>> [[Global]] (window) object in browsers has suffered. Give a hoot, don't
>>>> pollute.
>>>>
>>>> Post ES6 world makes creating emitter objects trivial—so why not a
>>>> blessed standard lib module that can be imported and used to extend a class
>>>> declaration?
>>>>
>>>>
>>>> import { Emitter } from "@event";
>>>>
>>>> class Foo extends Emitter {}
>>>>
>>>> Easy.
>>>>
>>>> More inline...
>>>>
>>>>
>>>>
>>>> On Wed, Jul 10, 2013 at 3:58 PM, Andrea Giammarchi <
>>>> [email protected]> wrote:
>>>>
>>>>> I know but people use prefixes and unique ids for events too and I am
>>>>> not sure if that would work so well.
>>>>>
>>>>> Also, this is not backward compatible, or better, this is impossible
>>>>> to polyfill so it won't bring benefits to the current scenario.
>>>>>
>>>>> If only I could already `Object.mixin(Object.mixin({}, EventEmitter),
>>>>> EventTarget)` and alias those prolix names as `on()` and `off()` it would
>>>>> be already great but this is too much in between the DOM, behind WebIDL,
>>>>> and ECMAScript ... something I know already historically incompatible,
>>>>> that's why I've proposed new names hopefully one day (and hopefully soon)
>>>>> in core, something that will be inherited in current implementation in any
>>>>> case, as it was in my case simply polluting the `Object.prototype` with
>>>>> those non enumerable properties luckily inherited in hosted DOM objects
>>>>> too.
>>>>>
>>>>> best regards
>>>>>
>>>>>
>>>>> On Wed, Jul 10, 2013 at 12:46 PM, Matthew Robb <[email protected]
>>>>> > wrote:
>>>>>
>>>>>> You can do chainability at object define time with the sugar form:
>>>>>>
>>>>>> var obj = {
>>>>>> on type1(){},
>>>>>> on type2(){},
>>>>>> on type3(){}
>>>>>> }
>>>>>>
>>>>>
>>>> This is the dark days of DOM element properties as event handlers:
>>>>
>>>> elem.onclick...
>>>>
>>>> Assigning to this paves over the previous assignment, leaving no way to
>>>> have multiple handlers registered for the same event type.
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>>> OR add to it using one of the following options:
>>>>>>
>>>>>> Object.mixin(obj, {
>>>>>> on type1(){},
>>>>>> on type2(){},
>>>>>> on type3(){}
>>>>>> })
>>>>>>
>>>>>> obj.{
>>>>>> on type1(){},
>>>>>> on type2(){},
>>>>>> on type3(){}
>>>>>> }
>>>>>>
>>>>>> obj := {
>>>>>> on type1(){},
>>>>>> on type2(){},
>>>>>> on type3(){}
>>>>>> }
>>>>>>
>>>>>>
>>>>>> On Wed, Jul 10, 2013 at 12:41 PM, Andrea Giammarchi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> my implementation works already with `DOM` nodes and browser
>>>>>>> environment, including `window`.
>>>>>>>
>>>>>>> I've also already written an `EventTarget` mixin object but in my
>>>>>>> case I'd use that via `Object.mixin(Object.prototype, EventTarget);`
>>>>>>> 'cause
>>>>>>> almost every object I use in my logic should be observed or should emit
>>>>>>> something to some other object.
>>>>>>>
>>>>>>
>>>> Standard lib approach (a la node) works today and tomorrow.
>>>>
>>>>
>>>>>
>>>>>>> Of course Dictionaries are out of the game but that's OK, as long as
>>>>>>> it's possible to promote them later on via `Object.setPrototypeOf(dict,
>>>>>>> Object.proottype)`
>>>>>>>
>>>>>>> I find the `Object.addEventListener(obj, "type", handler)` approach
>>>>>>> very boring for the simple reason that it does not make sense to use
>>>>>>> chainability there, another de-facto thing when it comes to events.
>>>>>>>
>>>>>>
>>>> It's also (subjectively) hideous.
>>>>
>>>>
>>>>
>>>>>
>>>>>>> ```javascript
>>>>>>> // current eddy.js status
>>>>>>> var obj = {}
>>>>>>> .on(type1, handler1)
>>>>>>> .on(type2, handler2)
>>>>>>> .on(type3, handler3)
>>>>>>> ;
>>>>>>> ```
>>>>>>>
>>>>>>
>>>> That's great for your use case, but I would never want this by default.
>>>>
>>>>
>>>> Rick
>>>>
>>>> (snip)
>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> [email protected]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> --
> Jeremy Martin
> 661.312.3853
> http://devsmash.com
> @jmar777
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss