就像我们睡觉一样,盖了三床被子,要从外面一层一层展开;躺进去后,再一层一层盖上一样。
koa 中的洋葱圈模型
在koa中,中间件是洋葱圈模型。什么是洋葱圈模型呢?
每一层都是一个中间件,先从外到里执行next前的处理,再由中心向外部执行next之后的处理。每一层都有两次执行时机。
我们先使用koa来看一下中间件执行的时机及过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const Koa = require('koa') const app = new Koa()
app.use((ctx, next) => { console.log('中间件1 -- next之前') next() console.log('中间件1 -- next之后') })
app.use((ctx, next) => { console.log('中间件2 -- next之前') next() console.log('中间件2 -- next之后') })
const port = 3000 app.listen(port, () => { console.log(`http://localhost:${port}`) })
|
执行如图所示
打印结果如下
1 2 3 4
| 中间件1 -- next之前 中间件2 -- next之前 中间件2 -- next之后 中间件1 -- next之后
|
简易的洋葱圈模型实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const { createServer } = require("node:http") class Koa { handlers = [] ctx = {} use(handler) { if (typeof handler !== "function") { throw new Error("middleware is must be a function") }
this.handlers.push(handler) }
_execute() { if (this.handlers.length === 0) return const first = this.handlers.shift()
first(this.ctx, () => { this._execute() }) }
listen(port, callback) { const app = createServer((req, res) => { this._execute()
res.writeHead(200, { "Content-type": "application/json" }) res.end( JSON.stringify({ status: 200, message: "hello my koa", }) ) })
app.listen(port, typeof callback === "function" ? callback : null) } }
const app = new Koa()
app.use((ctx, next) => { console.log("中间件1 -- next之前") next() console.log("中间件1 -- next之后") })
app.use((ctx, next) => { console.log("中间件2 -- next之前") next() console.log("中间件2 -- next之后") })
const port = 3000 app.listen(port, () => { console.log(`http://localhost:${port}`) })
|