什么是Koa?
Koa是一个精简的node
框架,被认为是第二代Node
框架,其最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型,它的核心工作包括下面两个方面:
- 将
node
原生的req
和res
封装成为一个context
对象。
- 基于
async/await
的中间件洋葱模型机制。
什么是洋葱模型。
Koa
的洋葱模型是以next
()函数为分割点,先由外到内执行Request
的逻辑,然后再由内到外执行Response
的逻辑,这里的request
的逻辑,我们可以理解为是next
之前的内容,response
的逻辑是next
函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose
方法
为什么需要洋葱模型?
因为很多时候,在一个app
里面有很多中间件,有些中间件需要依赖其他中间件的结果,用葱模型可以保证执行顺序,如果没有洋葱模型,执行顺序可能出乎我们的预期
如下是洋葱代码的案例:
const Koa = require('koa'); //Applications const app = new Koa(); // 中间件1 app.use((ctx, next) => { console.log(1); next(); console.log(2); }); // 中间件 2 app.use((ctx, next) => { console.log(3); next(); console.log(4); }); app.listen(7000, '0.0.0.0', () => { console.log(`Server is starting`); }); // 中间件的打印顺序是1 -> 3 -> 4 -> 2
总结
Koa
的洋葱模型指的是以 next
() 函数为分割点,先由外到内执行 Request
的逻辑,再由内到外执行 Response
的逻辑。通过洋葱模型,将多个中间件之间通信等变得更加可行和简单。其实现的原理并不是很复杂,主要是 compose
方法。
简易版 compose
模范 koa
的逻辑,我们可以写一个简易版的 compose
。方便大家的理解:
const middleware = [] let mw1 = async function (ctx, next) { console.log("next前,第一个中间件") await next() console.log("next后,第一个中间件") } let mw2 = async function (ctx, next) { console.log("next前,第二个中间件") await next() console.log("next后,第二个中间件") } let mw3 = async function (ctx, next) { console.log("第三个中间件,没有next了") } function use(mw) { middleware.push(mw); } function compose(middleware) { return (ctx, next) => { return dispatch(0); function dispatch(i) { const fn = middleware[i]; if (!fn) return; return fn(ctx, dispatch.bind(null, i+1)); } } } use(mw1); use(mw2); use(mw3); const fn = compose(middleware); fn();