拦截器是一个函数
async (ctx, next) => { do sth... }
|
它有两个参数。第一个参数是一个上下文,这个上下文在多个拦截切面中是共享的。第二个参数是一个 next 函数,调用它会进入下一个拦截切面。
class Interceptor { constructor() { this.aspects = []; }
use( functor) { this.aspects.push(functor); return this; }
async run(context) { const aspects = this.aspects;
const proc = aspects.reduceRight( function (a, b) { return async () => { await b(context, a); }; }, () => Promise.resolve() );
try { await proc(); } catch (ex) { console.error(ex.message); }
return context; } }
module.exports = Interceptor;
|
测试代码
function wait(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); }
const inter = new Interceptor();
const task = function (id) { return async (ctx, next) => { console.log(`task ${id} begin`); ctx.count++; await wait(1000); console.log(`count: ${ctx.count}`); await next(); console.log(`task ${id} end`); }; };
inter.use(task(0)); inter.use(task(1)); inter.use(task(2)); inter.use(task(3)); inter.use(task(4));
inter.run({ count: 0 });
|
使用拦截器的好处:控制业务流程,复用模块功能(拦截切面可以被共用,避免代码冗余)