Last active
September 8, 2021 01:36
-
-
Save zazaulola/dc732acc250c63ec41e2298937693f92 to your computer and use it in GitHub Desktop.
Primitive middleware router without timeout
This file contains hidden or 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
// Router is a function that returns async function. | |
const Router = (...chain) => | |
Object.assign( | |
// That async function as object have one method push() | |
async (ctx) => { | |
// When it calls that function it runs recursive algorithm | |
return await (async function run(idx) { | |
// Which calls each function in the chain | |
let res = await ("AsyncFunction" !== chain[idx].constructor.name | |
? new Promise((res) => chain[idx](ctx, res)) | |
: chain[idx](ctx)); | |
// If it returns any result it will terminate chain execution | |
return undefined != res | |
? res | |
: idx < chain.length - 1 | |
? await run(idx + 1) | |
: undefined; | |
})(0); | |
}, | |
{ push: (...mws) => chain.push(...mws) } | |
); | |
// Examples of use | |
let router = Router(); | |
// Each middleware is a function with 2 arguments | |
// first of it is context object | |
// second of it is callback | |
router.push((ctx, next) => { | |
console.log(1); | |
ctx.x++; | |
// call of the callback pass execution to next middleware | |
next(); | |
}); | |
let router2 = Router(); | |
// We can use async function as middleware | |
router2.push(async (ctx) => { | |
console.log(2); | |
ctx.x++; | |
}); | |
router2.push((ctx, next) => { | |
console.log(3); | |
ctx.x++; | |
next(); | |
//second call of the callback will be ignored | |
setTimeout(() => next(), 1000); | |
}); | |
// And we can use other router as middleware | |
router.push(router2); | |
router.push((ctx, next) => { | |
console.log(4); | |
ctx.x++; | |
setTimeout(next, 500); | |
}); | |
router.push((ctx, next) => { | |
console.log(5); | |
ctx.x++; | |
next(); | |
//second call of the callback will be ignored | |
next(true); | |
}); | |
router.push(async (ctx) => { | |
console.log(6); | |
ctx.x++; | |
// We can terminate chain execution | |
// if we return any other value except undefined | |
return undefined; | |
}); | |
router.push((ctx, next) => { | |
console.log(7); | |
ctx.x++; | |
// terminate chain execution | |
next(true); | |
}); | |
// that middleware will never be called | |
router.push((ctx, next) => { | |
console.log(8); | |
ctx.x++; | |
next(); | |
}); | |
(async () => { | |
let ctx = { x: 0 }; | |
let res = await router(ctx); | |
console.log("End"); | |
console.log("x=", ctx.x, "ctx=", ctx); | |
console.log(res); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment