洋葱模型(栈, 先进后出)
洋葱的表皮我们可以思考为中间件:
- 从外向内的过程是一个关键词 next();
- 而从内向外则是每个中间件执行完毕后,进入下一层中间件,一直到最后一层。
Express VS KOA
Express | KOA | |
---|---|---|
中间件 | 内置很多中间件 | 轻量, @koa/router需要单独引入 |
异步 | 基于callback处理 | 基于await/async |
洋葱模型执行中间件 | 非严格 | 严格遵循 |
优势 | 功能全,发展时间长 | 未来的趋势 |
原因: 基于nodejs的版本不同
Express 执行中间件
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('1');
next();
console.log('1 end');
})
app.use((req, res, next) => {
console.log('2');
next();
console.log('2 end');
})
app.use((req, res, next) => {
console.log('3');
next();
console.log('3 end');
})
app.get('/', function (req, res) {
res.send('Hello World')
})
app.listen(3000, () => console.log('listen 3000'))
// listen 3000
// 1
// 2
// 3
// 3 end
// 2 end
// 1 end
koa 执行中间件
const Koa = require('koa');
const app = new Koa();
app.use((ctx, next) => {
console.log('1');
next();
console.log('1 end');
})
app.use((ctx, next) => {
console.log('2');
next();
console.log('2 end');
})
app.use((ctx, next) => {
console.log('3');
next();
console.log('3 end');
})
app.use(ctx => {
ctx.body = 'Hello World';
})
app.listen(3000, () => console.log('listen 3000'))
// listen 3000
// 1
// 2
// 3
// 3 end
// 2 end
// 1 end
Express 执行异步中间件
const express = require('express')
const app = express()
app.use(async (req, res, next) => {
console.log('1');
await next();
console.log('1 end');
})
app.use(async (req, res, next) => {
console.log('2');
await next();
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log('wait');
resolve();
}, 1000)
})
console.log('2 end');
})
app.use(async (req, res, next) => {
console.log('3');
await next();
console.log('3 end');
})
app.get('/', function (req, res) {
res.send('Hello World')
})
app.listen(3000, () => console.log('listen 3000'))
// 1
// 2
// 3
// 3 end
// 1 end
// wait
// 2 end
koa 执行异步中间件
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
console.log('1');
await next();
console.log('1 end');
})
app.use(async (ctx, next) => {
console.log('2');
await next();
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log('wait');
resolve();
}, 1000)
})
console.log('2 end');
})
app.use(async (ctx, next) => {
console.log('3');
await next();
console.log('3 end');
})
app.use(ctx => {
ctx.body = 'Hello World';
})
app.listen(3000, () => console.log('listen 3000'))
// listen 3000
// 1
// 2
// 3
// 3 end
// wait
// 2 end
// 1 end