Created
February 4, 2020 17:04
-
-
Save danielyaa5/b664248a407c58416f0ae3b8d6697c93 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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