Skip to content

Instantly share code, notes, and snippets.

@zerkalica
Created January 26, 2015 14:56
Show Gist options
  • Save zerkalica/a160a67ef3297ab156a0 to your computer and use it in GitHub Desktop.
Save zerkalica/a160a67ef3297ab156a0 to your computer and use it in GitHub Desktop.
Semantic actions store example for flux
class ActionsBase {
constructor(dispatcher) {
this.dispatcher = dispatcher
this.key = null
}
_dispatch(data, suffix) {
this.dispatcher.dispatch(this.key + suffix, data)
}
dispatch(fn) {
this._dispatch(fn(), '')
}
dispatchAsync(fn) {
this._dispatch(null, 'Progress')
fn()
.then((payload) => this._dispatch(payload, 'Success'))
.catch((err) => this._dispatch(err, 'Fail'))
}
}
function getActionsConstants(proto) {
let constants = proto.__constants__
if (constants) {
return constants
}
constants = proto.__constants__ = []
let obj = proto.prototype
let key
let actionType
let fakeObj = {
dispatch() {
constants.push(key)
},
dispatchAsync() {
constants.push(key + 'Progress')
constants.push(key + 'Success')
constants.push(key + 'Fail')
}
}
for (let name in obj) {
if (!obj.hasOwnProperty(name)) continue
let fn = obj[name]
key = name
fn.apply(fakeObj)
obj[name] = function() {
this.key = name
return fn.apply(this, arguments)
}
}
return constants
}
function getActionSetsConstants(prototypes) {
let result = []
if (!Array.isArray(prototypes)) prototypes = [prototypes]
for(let i = 0; i < prototypes.length; i++) {
let constants = getActionsConstants(prototypes[i])
result = result.concat(constants)
}
return result
}
class StoreBase {
constructor(dispatcher) {
this.dispatcher = dispatcher
this.initialize()
}
initialize () {
let constants = getActionSetsConstants(this.getActions());
for (let i = 0; i < constants.length; i++) {
let message = constants[i]
if(typeof this[message] !== 'function') continue
this.dispatcher.on(message, this[message].bind(this))
}
}
}
class Dispatcher {
constructor() {
this.listeners = new Map()
}
dispatch(message, payload) {
this.listeners.get(message).forEach((fn) => {
fn(payload)
})
}
on(message, fn) {
if (!this.listeners.has(message)) this.listeners.set(message, [])
this.listeners.get(message).push(fn)
}
}
class MyActions extends ActionsBase {
addItemSync(item) {
this.dispatch(() => {
let value = 123
return item.test+ value
})
}
addItem(item) {
this.dispatchAsync(() => {
return new Promise((resolve, reject) => {
let value = 123
resolve(item.test + value)
})
})
}
}
class MyStore extends StoreBase {
getActions() {
return [MyActions]
}
addItemSync(item) {
console.log('addItemSync:', item)
}
addItemProgress(item) {
console.log('addItemProgress:', item)
}
addItemSuccess(item) {
console.log('addItemSuccess:', item)
}
}
let dispatcher = new Dispatcher()
let myStore = new MyStore(dispatcher)
let myActions = new MyActions(dispatcher)
myActions.addItemSync({test: 'sync'})
myActions.addItem({test: 'async'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment