var middlewarify = function(pre, done) {
var middleware = [];
var func = function(...args) {
if (done) middleware.push(done);
return middleware.reduce( (chain, fn) => chain.then(fn)
, Promise.resolve(pre.apply(null, args)))
};
func.use = function(fn){
middleware.push(fn);
};
return func;
};
var myLibrary = (function() {
var _doTheFirstThing = function(param1, param2) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ param1, param2 });
}, 100);
})
};
var _doTheLastThing = function(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
result.status = "success";
resolve(result);
}, 100);
})
};
return {
doSomething: middlewarify(_doTheFirstThing, _doTheLastThing)
};
})();
//This is how consumers would use your library's middleware enabled 'doSomething'
//Create an async middleware function
var middleware1 = function middleware1(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
result.middleware = "async"
resolve(result);
}, 100);
})
};
// Create a synchronouse middleware function
var synchronousMiddleware = function(result) {
result.middleware += " sync";
return result;
}
// Register the middleware
myLibrary.doSomething.use(middleware1);
myLibrary.doSomething.use(synchronousMiddleware);
// Actually execute.
// Order operations will be doTheFirstThing -> middleware1 -> synchronousMiddleware -> doTheLastThing
myLibrary.doSomething("value1", "value2").then(result => {
console.log("Done")
console.log(result);
/*
OUTPUT
=======
Done
{ param1: 'value1',
param2: 'value2',
middleware: 'async sync',
status: 'success' }
*/
});