/ node

白话koa2的洋葱模型

1
1.一个请求到一旦到后端,就开始接触洋葱的最外层。
2.遇到一个next(),就进入下一层。不过值得提醒的是,异步函数的next(),与同步函数的next(),不是在同一个空间的,我们可以假想一个“异步空间栈”,后入先出。
3.什么时候到洋葱中心?就是遇到的第一个没有next的中间件,或者遇到一个中间件报错,就会把这个中间件当成中心,因为遇到错误了,不会再继续往里面走。这个时候,就开始向洋葱的外层开始走了。如果第一个中间件就没有next,直接返回的。那么就不存在洋葱模型。
4.一层一层外面走的时候,就先走位所有的同步中间件,再依次走“异步空间栈”的中间件。

例子:

const Koa = require('koa');
const app = new Koa();
// Middleware 0
app.use((ctx,next) => {
    console.log('0-1');
    next();
    console.log('0-2');
})

// Middleware 1
app.use((ctx,next) => {
    console.log('1-1');
    next();
    console.log('1-2');
})

// Middleware 2
app.use(async(ctx, next) => {
    console.log('2-1');
    await next();
    console.log('2-2')
})

// Middleware 3
app.use(async(ctx, next) => {
    console.log('3-1');
    await next()
    console.log('3-2')
})

// Middleware 4
app.use((ctx,next) => {
    console.log('4-1');
    ctx.body = '4-1';
    console.log('4-2');
    next();
    ctx.status = 201;
    console.log('4-3');
})

// Middleware 5
app.use((ctx) => {
    console.log('5-1');
    ctx.body = '5-1';
    console.log('5-2');
})

// Middleware 6
app.use((ctx) => {
    console.log('6-1');
    ctx.body = '6-1';
    console.log('6-2');
})

app.listen(8010, () => console.log('listening on 8010'))

上面这个例子,写了0,1,2,3,4,5,6,共七个中间件。
但是 5 中没有next(),所以有洋葱只要6层,就到中心了,最后一个中间件无法执行。
整体上,当一个请求过来时,执行顺序是:
从1到5,一直往下走next()之上的,

console.log('0-1');
console.log('1-1');
console.log('2-1');
console.log('3-1');
console.log('4-1');
ctx.body = '4-1';
console.log('4-2');
console.log('5-1');

到中心之后,开始往外走,注意:异步空间栈

console.log('5-2');
ctx.status = 201;
console.log('4-3');
//本来该执行3的,但是已经被放在异步空间,继续外走
//本来该执行2的,但是已经被放在异步空间,继续外走
console.log('1-2');
console.log('0-2');
//以上同步的执行完了,然后把异步的拿出来依次执行
console.log('3-2')
console.log('3-2')

响应请求
从外到里,再走出来,ctx在中间件执行过程中,可能会被改变多次,后面的改变覆盖前面的。
最后把ctx响应给前端。