-
-
Save robinpokorny/d743ed9e0bc5214f79076a16c8e44a8f to your computer and use it in GitHub Desktop.
export default () => { | |
const subscribers = new Set() | |
const on = (fn) => { subscribers.add(fn) } | |
const off = (fn) => subscribers.delete(fn) | |
const emit = (data) => subscribers.forEach((f) => f(data)) | |
return Object.freeze({ on, off, emit }) | |
} |
import pubsub from './pubsub' | |
// Create a new PubSub | |
const events = pubsub() | |
// Register first subscriber | |
events.on((a) => console.log('one: ' + a)) | |
const two = (a) => console.log('two: ' + a) | |
// Register second subscriber | |
events.on(two) | |
// Subscriber can be registred only once, the following has no effect | |
events.on(two) | |
// Dispatch a string | |
// `two` is called just once | |
events.emit('foo') | |
// "one: foo" | |
// "two: foo" | |
// Deregister a subscriber | |
// Returns true if the function has been removed successfully | |
events.off(two) // true | |
// Dispatch a string | |
// `two` is not called | |
events.emit('bar') | |
// "one: bar" |
As suggested by @rarous (https://twitter.com/alesroubicek/status/764068304080089089) the on
can return an unsub callback and remove the off
method:
const on = (fn) => {
subscribers.add(fn)
return () => subscribers.delete(fn)
}
OK, so I liked that idea that much I made it the default. See the original version: https://gist.github.com/robinpokorny/d743ed9e0bc5214f79076a16c8e44a8f/f187d1d45873b1687e0a6d1f754a7aa073736742
I changed the API so the functions exposed are named sub
and pub
.
Also, because of the API changes it is not 5-line anymore 😞
I added a minified/uglified version which fits in a tweet!
Also note that module.exports=
is the exact same length as export default
(16 characters). So you can easily use it in node.js (>=v0.12) without transpiling.
What I used / found out:
- Moved functions definitions inside
Object.freeze
. {s.add(f);return _=>s.delete(f)}
tos.add(f).delete.bind(s,f)
. AsSet.prototype.add()
returns the Set object we can then access theSet.prototype.delete()
._=>
is one character less than()=>
and works the same! Of course, any letter would do, too.const
is 5 letters,var
andlet
just 3. If it works withconst
it will work withvar
andlet
.
The following has only 104 bytes, but allows a param during init:
export default (s=new Set)=>Object.freeze({pub:d=>s.forEach(f=>f(d)),sub:f=>s.add(f).delete.bind(s,f)})
I decided not to use this one as it is potentially dangerous.
Oh, the very minimal version would be 91 characters:
export default (s=new Set)=>({pub:d=>s.forEach(f=>f(d)),sub:f=>s.add(f).delete.bind(s,f)})
That is removing Object.freeze
. I would not recommend using that one though…
This gist's motivation was to create the simplest full-feature PubSub service.
One might want to check that argument of
on
is a function to prevent a future type error.Some inspiration: https://gist.github.com/learncodeacademy/777349747d8382bfb722