中间件 
老牌框架express和koa创建了中间件的概念,其中koa的中间件因为采用洋葱模型而广受业界好评。受此熏陶,本框架采用与koa同样的中间件逻辑

第一个中间件 
从核心包导出middleware对象即可快速创建一个中间件
typescript
import { middleware } from '@aomex/core';
export const md = middleware.mixin(async (ctx, next) => {
  console.log('enter');
  await next();
  console.log('exit');
});ctx是一个对象,穿梭在各个中间件,可以获取属性和设置新的属性。next是一个函数,代表继续执行下一个中间件
类型提示 
默认地,ctx变量的初始类型为object,因此在.ts文件中如果想操作对象,则会发生类型报错。
typescript
export const md = middleware.mixin(async (ctx, next) => {
  ctx.foo = 'bar';
       ⤷ Property 'foo' does not exist on type 'object'. 
  await next();
});
console.log(md); // MixinMiddleware<object>对于TS项目,这能忍?框架不能忍。为此中间件提供了泛型策略,既能提示内部函数,也能自动导出对外使用,一举两得
typescript
interface Props {
  readonly foo: string;
}
export const md = middleware.mixin<Props>(async (ctx, next) => {
  ctx.foo = 'bar';
  await next();
});
console.log(md); // MixinMiddleware<{ readonly foo: string }>执行顺序 
正如开头看到的那张图,中间件遵循洋葱模型,从左边往右依次执行,接着从右往左反向执行。
typescript
import { compose } from '@aomex/core';
const a = middleware.mixin(async (ctx, next) => {
  console.log(1);
  await next();
  console.log(6);
});
const b = middleware.mixin(async (ctx, next) => {
  console.log(2);
  await next();
  console.log(5);
});
const c = middleware.mixin(async (ctx, next) => {
  console.log(3);
  await next();
  console.log(4);
});
// 输出:1 2 3 4 5 6
await compose([a, b, c])({});