mitt icon indicating copy to clipboard operation
mitt copied to clipboard

Return unsub function from on()

Open ajoslin opened this issue 8 years ago • 9 comments

195b. Forked from #1.

  • Don't assign all[type] in .off()
  • Use a slightly more space-efficient assignment ofall[type] in .on() (no parens).
  • Return a bound splice from .on().

The one thing I can't figure out is the why the "off() should normalize case" test is failing now. In fact, I don't see how it ever worked.

ajoslin avatar Feb 28 '17 06:02 ajoslin

We still not consider #1, so this will be delayed too...

I'm still strongly against that. Since we promote to be "compat" with Node EE. We still are totally not compat in any terms, but yea..

tunnckoCore avatar Feb 28 '17 06:02 tunnckoCore

Alright, I just pushed. if we replace Object.create(null) with {} at the beginning, we can fit a bound off in 193b. I'm still getting the weird failing test about off normalizing case, though.

Regarding this not being compatible with EE.. This library isn't at all compatible with EventEmitter at the moment. .off() does not exist in EventEmitter, for example. I'd say it's in the "spirit" of EventEmitter, but no more.

ajoslin avatar Feb 28 '17 16:02 ajoslin

object create is intentional. and yea exactly wat i mean

tunnckoCore avatar Feb 28 '17 16:02 tunnckoCore

I'm guessing the purpose of Object.create(null) here is to allow event names using object prototype names? Is that correct?

ajoslin avatar Feb 28 '17 17:02 ajoslin

Yes. Wanted and merged.

In reality we can go down to ~160-170 if we drop off and make on return unsubscribe. If i remember i tried it already. If that's the way to go with mitt, i'm giving up and going to make another lib.

edit: If we are more strict we even can remove the method names and be a single method :D

tunnckoCore avatar Feb 28 '17 18:02 tunnckoCore

What about this one then

function dush (all) {
  all = all || Object.create(null)
  return function onOrEmit (name, handler) {
    if (typeof handler === 'function') {
      var e = (all[name] || (all[name] = []))
      e.push(handler)

      return function off (name) {
        (name && (all[name] = [])) || e.splice(e.indexOf(handler) >>> 0, 1)
      }
    }
    all[name].map((f) => { f(handler) })
  }
}

example

var emitter = dush()

// .on
emitter('foo', (data) => console.log('one', data))
var offBar = emitter('bar', (data) => console.log('bar1', data))
emitter('bar', (data) => console.log('bar2', data))
var offFoo = emitter('foo', (data) => console.log('two', data))

// .emit
emitter('foo', 123)

// off all foo
offFoo('foo')

emitter('foo', 'not emitted')
emitter('bar', 'woohoo')

// off all bar
offBar('bar')

emitter('bar', 33)
emitter('foo', 33)

tunnckoCore avatar Feb 28 '17 18:02 tunnckoCore

That looks a lot like the observed value syntax from Mithril. Separate lib tho :P

Think we should rename off? You're right about EE compat, I took that name from Wildemitter

developit avatar Feb 28 '17 18:02 developit

Returning an unsubscribe function from the subscription is the same approach I've been using in brcast. https://github.com/vesparny/brcast/blob/b5834dc95faad93809c26df54729fba5bfef4e67/index.js#L25

When having a lot of handlers subscriptions/unsubscriptions this implementation is apparently heavier in terms of memory consumption. Probably because a function is allocated every time a subscription is created.

This has been reported to the styled-components repository which uses a similar implementation.

@developit what do you think?

vesparny avatar Jul 31 '17 13:07 vesparny

^ Yes

developit avatar Dec 07 '17 02:12 developit