Last active
July 1, 2016 12:48
-
-
Save eser/3944ba9ccf99810492acb01d5f21ade2 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
class MiddlewareProxyHandler { | |
constructor() { | |
this.middlewares = []; | |
// this.ignoredKeys = [ 'meta' ]; | |
} | |
addMiddleware(obj) { | |
this.middlewares.push(obj); | |
} | |
get(target, propertyKey, receiver) { | |
// if (this.ignoredKeys.indexOf(propertyKey) > -1) { | |
// return target[propertyKey]; | |
// } | |
let callStack = [], | |
callStackIndex = 0, | |
result = undefined; | |
for (let middleware of this.middlewares) { | |
if (middleware[propertyKey] !== undefined) { | |
if (middleware[propertyKey] !== null && middleware[propertyKey].constructor === Function) { | |
if (callStack.length === 0) { | |
(function (resultParameter) { | |
callStack.push({ scope: undefined, callback: (next) => next(resultParameter) }); | |
})(result); | |
} | |
callStack.push({ scope: middleware, callback: middleware[propertyKey] }); | |
} | |
else { | |
callStack = []; | |
result = middleware[propertyKey]; | |
} | |
} | |
} | |
if (callStack.length === 0) { | |
target[propertyKey] = result; | |
return target[propertyKey]; | |
} | |
const next = function () { | |
const current = callStack[callStackIndex++]; | |
if (current === undefined) { | |
return arguments[0]; | |
} | |
const parameters = Array.prototype.slice.call(arguments, 0); | |
parameters.push(next); | |
return current.callback.apply(current.scope, parameters); | |
}; | |
target[propertyKey] = next; | |
return target[propertyKey]; | |
} | |
} | |
function consultant(obj) { | |
const handler = new MiddlewareProxyHandler(), | |
instance = new Proxy(obj, handler); | |
return { | |
meta: handler, | |
instance: instance | |
}; | |
} | |
const c = consultant({}); | |
c.meta.addMiddleware({ a: (x, next) => next(5) }); // first | |
c.meta.addMiddleware({ a: (x, next) => next(x * 2) }); // second | |
c.meta.addMiddleware({ a: (x, next) => next(x + 1) }); // third | |
c.meta.addMiddleware({ b: 'eser' }); // first | |
c.meta.addMiddleware({ b: (x, next) => next(x.toUpperCase()) }); // second | |
c.meta.addMiddleware({ c: 777 }); // first | |
const p = c.instance; | |
console.log(`a: ${p.a()} | |
b: ${p.b()} | |
c: ${p.c}`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment