Skip to content

Instantly share code, notes, and snippets.

@sandeep1995
Last active June 12, 2018 06:37
Show Gist options
  • Save sandeep1995/b97f7a0005c9c316ca3f7c4df79889ea to your computer and use it in GitHub Desktop.
Save sandeep1995/b97f7a0005c9c316ca3f7c4df79889ea to your computer and use it in GitHub Desktop.
Example of promise based event hooking
const lifeCycleInstance = Symbol('LifeCycleInstance');
const singletonEnforcer = Symbol('SingletonEnforcer');
const VU_DRAWN_EVT = 'visual-unit.drawn';
const CANVAS_INIT_EVT = 'canvas.init';
const EVENT_LIST = [VU_DRAWN_EVT, CANVAS_INIT_EVT];
const resolver = resolveFn => notifier => resolveFn(notifier);
class LifeCycleManager {
constructor(enforcer) {
if (enforcer !== singletonEnforcer) {
throw new Error('Can not construct LifeCycle');
}
this._eventList = EVENT_LIST;
this._promises = new Map();
this._notifiers = {};
this._init();
}
_init() {
this._notifiers = this._eventList.reduce((acc, name) => {
acc[name] = resolver;
return acc;
}, {});
this._initPromises();
}
retrieve(promiseName) {
return this._promises.get(promiseName);
}
_makeNotifierPromise(eventName) {
return new Promise((resolve) => {
this._notifiers[eventName] = this._notifiers[eventName](resolve);
});
}
_initPromises() {
this._eventList.forEach((eventName) => {
this._promises.set(eventName, this._makeNotifierPromise(eventName));
});
}
notify(notifier) {
let formalName = notifier.formalName || notifier.client.constructor.formalName();
this._notifiers[`${formalName}.${notifier.action}`](notifier);
}
static get instance() {
if (!this[lifeCycleInstance]) {
this[lifeCycleInstance] = new LifeCycleManager(singletonEnforcer);
}
return this[lifeCycleInstance];
}
}
// ----------- Picasso Library --------------- //
class VisualUnit {
constructor() {
this.lifeCycleManager = LifeCycleManager.instance;
}
static formalName() {
return 'visual-unit';
}
draw() {
console.log('drawing visual-unit');
}
}
class Canvas {
constructor() {
console.log('init canvas');
this.lifeCycleManager = LifeCycleManager.instance;
this.lifeCycleManager.notify({
client: this,
action: 'init'
});
}
static formalName() {
return 'canvas';
}
hooks(hookList) {
const promiseBag = [];
hookList.forEach(hookName => {
promiseBag.push(this.lifeCycleManager.retrieve(hookName));
});
return promiseBag;
}
mount() {
// create multiple visual units
let units = [];
for (let i = 0; i < 10; i++) {
let visualUnit = new VisualUnit();
visualUnit.draw();
units.push(visualUnit);
}
this.lifeCycleManager.notify({
client: units,
action: 'drawn',
formalName: 'visual-unit'
});
}
}
// -------------- User Code ------------ //
let canvas = new Canvas();
const promises = canvas.hooks(['visual-unit.drawn', 'canvas.init']);
Promise.all(promises).then(d => {
console.log(d);
})
canvas.mount();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment