洋葱模型(栈, 先进后出)
洋葱的表皮我们可以思考为中间件:
- 从外向内的过程是一个关键词 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
