Created
August 8, 2017 08:58
-
-
Save riyaz-ali/9a6c421664cdff14b5d18543e24afe60 to your computer and use it in GitHub Desktop.
A Promise-based middleware implementation in ES6
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
let moo = new Middleware() | |
moo.use(function step1(next, start){ | |
console.log(`#1 - ${start}`) | |
setTimeout(() => next('Hello from #1'), 2000) | |
}) | |
moo.use(function step2(next, from1){ | |
console.log(`#2 - ${from1}`) | |
next('Hello from #2') | |
//next(new Error('error from #2')) //- call next with error and the promise will be rejected. | |
//throw new Error('error from #2') //- you can even throw from within the middleware function | |
}) | |
moo.exec('begin').then(function(result){ | |
console.log(`DONE - ${result}`) | |
}).catch(function(error){ | |
console.error(error) //- comment line 10 and uncomment line 11 to throw an error from within middleware | |
}) |
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
//- A Promise-based middleware implementation | |
let nextTick = 'undefined' !== typeof process | |
? process.nextTick | |
: 'undefined' !== typeof setImmediate | |
? setImmediate | |
: setTimeout; | |
class Middleware { | |
/** create a new Middleware */ | |
constructor(){ | |
this.middlewares=[] | |
} | |
/** add a function to middleware stack */ | |
use(fn){ | |
if(!fn || typeof fn !== "function"){ | |
throw new TypeError("Argument to use must be of type 'Function'") | |
} | |
this.middlewares.push(fn) | |
} | |
/** execute the middlewares */ | |
exec(...args){ | |
return new Promise((resolve, reject) => { | |
// check for early exit | |
if(!this.middlewares.length) | |
return resolve(...args) | |
// kickstart the chain | |
let _execute = (i, ...args0) => { | |
// use nextTick function to post this as a new task on the Task queue | |
nextTick(() => { | |
try { this.middlewares[i]((...returnValue) => { | |
if(returnValue.length && returnValue[0] instanceof Error) | |
return reject(returnValue[0]) | |
else if(i >= this.middlewares.length - 1) | |
return resolve(...returnValue) | |
else | |
return _execute(i+1, ...returnValue) | |
}, ...args0) } catch(err) { reject(err) } | |
}, 1) | |
} | |
_execute(0, ...args) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Checkout demo at https://jsfiddle.net/66u0wopv/