# 一、异步编程

# 1、callback 回调

# 2、ES6 的 Promise

# 3、Generator

Generator 函数的含义与用法 (opens new window)

# 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 中间件:

# 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

参考文章:Egg.js 与 Koa (opens new window)

# 3、与 redux

参考文章:Redux and the onion model: a simple guidance (opens new window)

# 二、源码分析

# 1、express

# 2、koa

更新于 : 8/7/2024, 2:16:31 PM