Skip to content

Instantly share code, notes, and snippets.

@danielyaa5
Created February 4, 2020 17:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielyaa5/b664248a407c58416f0ae3b8d6697c93 to your computer and use it in GitHub Desktop.
Save danielyaa5/b664248a407c58416f0ae3b8d6697c93 to your computer and use it in GitHub Desktop.
// Implement an EventManager class
//
// There should be three methods on this class:
//
// 1. subscribe(eventType: string, listener: Function)
// 2. unsubscribe(eventType: string, listener: Function)
// 3. publish(eventType: string, data: any)
//
// You can use either ES5 or ES6 notation
function syncSleep(ms) {
var start = new Date().getTime(),
expire = start + ms;
while (new Date().getTime() < expire) {}
return;
}
const callWithContext = (cb, data, context) => {
if (context) {
console.log(context);
return cb.call(context, data);
}
cb(data);
}
const tryCb = (data, cb, context, options) => {
try {
if (options.asychronous) return setTimeout(() => callWithContext(cb, data, context), 0);
callWithContext(cb, data, context);
} catch(_) {}
};
class EventManager {
constructor() {
this.channels = {};
}
subscribe(channelName, cb, options = { asynchronous: false }) {
this.channels[channelName] = this.channels[channelName] || [];
this.channels[channelName].push([cb, options]);
}
publish(channelName, data, context) {
if (!this.channels[channelName]) return false;
this.channels[channelName].forEach(([cb, options]) => tryCb(data, cb, context, options));
return true;
}
unsubscribe(channelName, cb) {
if (!this.channels[channelName]) return false;
let found = false;
this.channels[channelName] = this.channels[channelName].filter(([currCb, _]) => {
if (currCb === cb) found = true;
return currCb !== cb;
});
return found;
}
}
const channel = new EventManager();
const callback1 = data => { console.log('Callback 1:', data, this); };
const callback2 = data => console.log('Callback 2:', data, this);
const callback3 = data => console.log('Callback 3:', data, this);
channel.subscribe('request.error', callback1, { asynchronous: true });
channel.subscribe('request.error', callback2);
channel.subscribe('request.success', callback3);
channel.publish('request.error', { foo: 'bar' });
channel.publish('request.success', { lorem: 'ipsum' }, 10);
// Expected output in console:
//
// Callback 1: { foo: 'bar' }
// Callback 2: { foo: 'bar' }
// Callback 3: { lorem: 'ipsum' }
channel.unsubscribe('request.error', callback1);
channel.publish('request.error', { bar: 'baz' });
// Expected output in console:
//
// Callback 2: { bar: 'baz' }
function foo(data) { console.log(this); console.log(data); }
foo.call('test', 'data')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment