Git Product home page Git Product logo

Comments (9)

stephband avatar stephband commented on July 18, 2024 1

Oh I see, fair enough. Thanks for writing out your use case :)

from mitt.

developit avatar developit commented on July 18, 2024

Interesting that there is such a disparity between Element#addEventListener() and EventEmitter#on(). I agree that #1 is likely smaller and more ergonomic, just want to keep this thing as tiny as possible :)

FWIW the quickest way to achieve deduping today would be:

let e = mitt();
function handler() {}
e.off('foo', handler);
e.on('foo', handler);

(same as how people achieve this with Node's EventEmitter)

from mitt.

dotproto avatar dotproto commented on July 18, 2024

Ah, I haven't worked much with EventEmitter so that pattern was new to me. In that case the primary argument of this issue doesn't hold much ground: the current API does provide facilities to ensure a single type-event registration.

from mitt.

developit avatar developit commented on July 18, 2024

@SVincent admittedly, I'd forgotten the DOM behaved differently. Now I have to wonder why EventEmitter didn't emulate that, given it was the most significant prior art - interesting things 😃. Not sure what to do with this issue now, since we're stuck in the middle!

from mitt.

dotproto avatar dotproto commented on July 18, 2024

Now I have to wonder why EventEmitter didn't emulate that, given it was the most significant prior art

My best guess is that because EventEmitter's design is more flexible. A dev can emulate DOM events with EventEmitter, but can't emulate EventEmitter with DOM events.

Not sure what to do with this issue now, since we're stuck in the middle!

IMO mitt should stick with it's current behavior and add additional docs to describe how to dedupe for the following reasons:

  1. It seems minimizing Byte size is an explicit goal of the project. As such I assume anything that inflates the size must provide significant value.
  2. The current API can be used to avoid duplicate type-handler registration, albeit in a slightly counterintuitive way.
  3. I think documentation can largely address the counter-intuitive aspect.
  4. I assume one of the major draws this lib is the balance of readability an minimal size. If a developer is trying to minimize bytes, they'll likely be willing to deal with a slightly less ergonomic API.
  5. If mitt adopted first-class deduping, then EventEmitter-like behavior would not be possible. I suspect there are completely legitimate and desirable use-cases for capturing a single event multiple times.
  6. If a more ergonomic way to dedupe becomes a common user request, you can always re-visit this issue.

As a side note, I spent some time last night trying to prototype a few different patches for this. The flag one is around +14 bytes gzipped (213 b).

from mitt.

developit avatar developit commented on July 18, 2024

wow, much appreciated rundown of your reasoning, I completely agree. Documentation needs to come first, which fixes the possibility of this being seen as a bug (instead its a feature). Then we're sitting on your (very nice) flag implementation should the requests start flowing in. 14 bytes is really good, so if there ends up being a way to shave 13 bytes of the current 199b size, this is probably top of the list along with the Object.create(null) fix.

from mitt.

stephband avatar stephband commented on July 18, 2024
let e = mitt();
function handler() {}
e.off('foo', handler);
e.on('foo', handler);`

Are you sure this works? Because, somewhat related to deduping in .on(), .off() does not remove all instances of handler, just the first, as there is only one .indexOf() in .off():

off(type, handler) {
    let e = list(type),
        i = e.indexOf(handler);
    if (~i) e.splice(i, 1);
},

Perhaps:

function remove(e, handler, index) {
    let i = e.indexOf(handler, index);
    if (i === -1) return;
    e.splice(i, 1);
    remove(e, handler, i);
}

...

off(type, handler) {
    remove(list(type), handler, 0);
},

Personally, in my experience 1) you almost never want duplicate handlers, and 2) you do want to be confident that .off() has really removed all instances of handler from the list.

from mitt.

dotproto avatar dotproto commented on July 18, 2024

It works in that calling off() before on() provides mItt users with a mechanism to dedupe, albeit not a built in one. For example, say I have a counter module that other parts of my app will use to get updates when an increment occurs.

let counter = (function() {
  let e = mitt();
  let type = 'increment';
  let count = 0;

  return {
    inc() {
      e.emit(type, { was: count, is: ++count});
      return count;
    },
    on(cb) {
      e.off(type, cb);
      e.on(type, cb);
    },
    off(cb) {
      e.off(type, cb);
    }
  }
})();

Since counter is exposing it's own interface for other parts of the app, I can ensure that duplicate to my module's on() function won't lead to duplicate handlers registered on my module's mitt instance.

// First, let's register a 1 callback several times
counter.on(console.log);
counter.on(console.log);
counter.on(console.log);

// … and increment to see what happens
counter.inc(); // console logs 1x

// Next, let's remove the callback we registered
counter.off(console.log);

// … and increment to see what happens
counter.inc(); // console does not log

from mitt.

developit avatar developit commented on July 18, 2024

Just a note - I am not aware of any emitter implementations that remove all instances of a handler.

To add to @SVincent's great rundown of use-cases - methods shared via the prototype needent be deduped.

I still find this an interesting trade-off on both sides, but one of the more convincing arguments for me is that skipping deduplication & remove-all saves some bytes 💅

from mitt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.