-
-
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.constis 5 letters,varandletjust 3. If it works withconstit will work withvarandlet.
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
onis a function to prevent a future type error.Some inspiration: https://gist.github.com/learncodeacademy/777349747d8382bfb722