DroopyTersen
10/20/2016 - 2:54 AM

promise-driven-middleware.js

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' }
*/
});