JSFiddle - React, Tailwind, and code Playground
by dirvann
JavaScript
/**
* returns a function with parameters as input that
* runs all the given functions sequentially
* @return function(...funcParams)
*/
function funcWrapper(...funcs) {
function exec(s,fs, ...dat) {
s< fs.length - 1?
fs[s](...dat, () => exec(++s, fs, ...dat)):
fs[s](...dat)
}
return exec.bind(null,0, funcs)
}
/**
* simulation of a class extending EventEmitter
*/
class emitterClass {
constructor() {
this.listeners = new Map()
}
/**
* add listener with multiple functions
*/
on(name, ...func) {
if(!this.listeners.has(name)) this.listeners.set(name, [])
// create a wrapper function from all the functions
let f = funcWrapper(...func)
this.listeners.get(name).push(f)
}
/**
* emit function is unchanged from the original
*/
emit(name, ...data) {
if(!this.listeners.has(name)) return
this.listeners.get(name).forEach(func => func(...data))
}
}
// usage
////// regular behavior still the same ///////
let l = new emitterClass()
l.on('users', (data) => console.log('userdata:',data))
l.emit('users', {name: 'mark'})
// "userdata: { name: 'mark' }"
///// regular multiple parameters //////
let s = new emitterClass()
s.on('users', (data, data2) => {
console.log('userdata:',data, 'second: ', data2)
})
s.emit('users', {name: 'mark'}, {name: 'josh'})
// "userdata: { name: 'mark' } second: { name: 'josh' }"
///// multiple middleware functions//////
function addAge(data, next) {
if(data.name === 'mark') {
data.age = 45
}
next()
}
function addJob(data, next) {
// some database information for example
if(data.name === 'mark') {
data.job = 'jobless'
}
next()
}
let r = new emitterClass()
r.on('users', addAge, addJob, console.log)
r.emit('users', {name:'mark'})
// "{ name: 'mark', age: 45, job: 'jobless' }"
///// multiple middleware fns + multiple params //////
function addAge2(data, data2, next) {
if(data.name === 'mark') {
data.age = 45
}
data2.age = 24
...