# 一、异步编程
# 1、callback 回调
略
# 2、ES6 的 Promise
略
# 3、Generator
# 4、ES8 的 async
略
# 一、中间件
提示
洋葱模型最早诞生与 koa,但 onion model 这个名称首次提到是在 egg.js 中。
# 洋葱模型
文章参考:Koa Middlewares Koa (opens new window)、Mastering Koa Middleware (opens new window)、How Koa middleware works (opens new window)
洋葱图:
执行顺序图:
compose 中间件:
- koa-compress (opens new window) for Koa.
- compression (opens new window) for Express.
# 1、与 express
在 koa 中所有的请求经过一个中间件的时候都会执行两次,
对比 Express 形式的中间件,Koa 的模型可以非常方便的实现后置处理逻辑。例如:
- err 错误中间件
- 异步请求数据
express 中的线性模型的缺陷
const express = require('express')
const axios = require('axios')
const app = express()
app.use((req, res, next) => {
console.log('step 1')
req.msg = '-2022-'
next()
})
app.use((req, res, next) => {
console.log('step 2')
req.msg += '-10-'
next()
})
// 执行异步代码
app.use(async (req, res, next) => {
console.log('step 3')
const result = await axios.get('https://jsonplaceholder.typicode.com/posts/1')
req.msg += result.data.body
// 只能👀在这里返回结果
res.json(req.msg)
})
app.listen(6061)
原因呢?express 中的 next()返回的是 void,而 koa 中的 next() 返回的是 Promise
理解
在执行同步代码的情况下,express 和 koa 都可以通过 use 依次注册中间件,依次执行代码逻辑。
但在执行异步代码时,express 是无法将当前中间件的 response 结果向上游传递的(callback 回调),而 koa 却可以依靠其洋葱模型的第二次执行达到目的(await/async)。
const Koa = require('koa')
const axios = require('axios')
const app = new Koa()
app.use(async (ctx, next) => {
console.log('step 1')
ctx.msg = '-2022-'
await next() // 此处返回的是一个promise
console.log('step 1')
// 在上游返回结果
ctx.body = ctx.msg
})
app.use(async (ctx, next) => {
console.log('step 2')
ctx.msg += '-10-'
await next()
console.log('step 2')
})
app.use(async (ctx, next) => {
console.log('step 3')
const result = await axios.get('https://jsonplaceholder.typicode.com/posts/1')
ctx.msg += result.data.body
// 在下游返回结果
// ctx.body = ctx.msg
})
app.listen(6061)
# 2、与 egg.js
# 3、与 redux
参考文章:Redux and the onion model: a simple guidance (opens new window)
# 二、源码分析
# 1、express
略
# 2、koa
略