Last active
June 12, 2018 06:37
-
-
Save sandeep1995/b97f7a0005c9c316ca3f7c4df79889ea to your computer and use it in GitHub Desktop.
Example of promise based event hooking
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
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