Skip to content

Instantly share code, notes, and snippets.

@ryanmorr
Last active March 29, 2024 06:37
Show Gist options
  • Save ryanmorr/5b9cccdb85078e6e572d316783584064 to your computer and use it in GitHub Desktop.
Save ryanmorr/5b9cccdb85078e6e572d316783584064 to your computer and use it in GitHub Desktop.
Add middleware to any callback function
function callbackMiddlewareProxy(callback) {
const middleware = [];
const push = middleware.push.bind(middleware);
return new Proxy(callback, {
get: (target, prop) => {
if (prop === 'use') {
return push;
}
return target[prop];
},
apply: (target, ctx, args) => {
let index = 0;
let returnValue;
const next = () => {
const mw = middleware[index++];
if (mw) {
mw.call(this, ...args, next);
} else {
returnValue = target.apply(ctx, args);
}
};
middleware[index++].call(this, ...args, next);
return returnValue;
}
})
}
// Usage:
const callback = callbackMiddlewareProxy((a, b, c) => a + b + c);
callback.use((a, b, c, next) => next());
callback.use((a, b, c, next) => next());
callback.use((a, b, c, next) => next());
callback(10, 20, 30); //=> 60
function callbackMiddleware(callback, middleware) {
return function(...args) {
let index = 0;
let returnValue;
const next = () => {
const mw = middleware[index++];
if (mw) {
mw.call(this, ...args, next);
} else {
returnValue = callback.apply(this, args);
}
};
middleware[index++].call(this, ...args, next);
return returnValue;
}
}
// Usage:
const middleware1 = (a, b, c, next) => next();
const middleware2 = (a, b, c, next) => next();
const middleware3 = (a, b, c, next) => next();
const callback = callbackMiddleware((a, b, c) => a + b + c, [middleware1, middleware2, middleware3]);
callback(10, 20, 30); //=> 60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment