Skip to content

Instantly share code, notes, and snippets.

@SaulDoesCode
Created May 2, 2018 12:36
Show Gist options
  • Save SaulDoesCode/e57ea4b12d83e0f268b117487f650b9b to your computer and use it in GitHub Desktop.
Save SaulDoesCode/e57ea4b12d83e0f268b117487f650b9b to your computer and use it in GitHub Desktop.
emitter with proxy powers
const infinify = (fn, reflect = false) => new Proxy(fn, {
get: (fn, key) =>
reflect && key in fn ? Reflect.get(fn, key) : fn.bind(undefined, key)
})
export default (host = {}, listeners = new Map()) => Object.assign(host, {
listeners,
emit: infinify((event, ...data) => {
if (listeners.has(event)) {
for (const h of listeners.get(event)) {
h.apply(undefined, data)
}
}
}),
emitAsync: infinify((event, ...data) => setTimeout(() => {
if (listeners.has(event)) {
for (const h of listeners.get(event)) {
setTimeout(h, 0, ...data)
}
}
}, 0), false),
on: infinify((event, handler) => {
if (!listeners.has(event)) listeners.set(event, new Set())
listeners.get(event).add(handler)
const manager = () => host.off(event, handler)
manager.off = manager
manager.on = () => {
manager()
return host.on(event, handler)
}
manager.once = () => {
manager()
return host.once(event, handler)
}
return manager
}),
once: infinify((event, handler) => host.on(event, function h () {
handler(...arguments)
host.off(event, h)
})),
off: infinify((event, handler) => {
if (listeners.has(event)) {
const ls = listeners.get(event)
ls.delete(handler)
if (!ls.size) listeners.delete(event)
}
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment