晴明的博客园 GitHub      CodePen      CodeWars     

[js] 中间件的洋葱模型

Express 的中间件

var express = require('express')
var app = express()

app.use(function middleware1(req, res, next) {
  console.log('A middleware1 开始')
  next()
  console.log('B middleware1 结束')
})

app.use(function middleware2(req, res, next) {
  console.log('C middleware2 开始')
  next()
  console.log('D middleware2 结束')
})

app.use(function middleware3(req, res, next) {
  console.log('E middleware3 开始')
  next()
  console.log('F middleware3 结束')
})

app.get('/', function handler(req, res) {
  res.send('ok')
  console.log('======= G =======')
})

if (module.parent) {
  module.exports = app
} else {
  app.listen(8080)
}

output:
A middleware1 开始
C middleware2 开始
E middleware3 开始
======= G =======
F middleware3 结束
D middleware2 结束
B middleware1 结束

            --------------------------------------
            |            middleware1              |
            |    ----------------------------     |
            |    |       middleware2         |    |
            |    |    -------------------    |    |
            |    |    |  middleware3    |    |    |
            |    |    |                 |    |    |
          next next next  ———————————   |    |    |
请求 ——————————————————> |  handler  | — 收尾工作->|
响应 <—————————————————  |     G     |  |    |    |
            | A  | C  | E ——————————— F |  D |  B |
            |    |    |                 |    |    |
            |    |    -------------------    |    |
            |    ----------------------------     |
            --------------------------------------


顺序 A -> C -> E -> G -> F -> D -> B
    \---------------/   \----------/
            ↓                ↓
        请求响应完毕        收尾工作

Redux 的中间件

<!DOCTYPE html>
<html>
<head>
  <script src="//cdn.bootcss.com/redux/3.5.2/redux.min.js"></script>
</head>
<body>
<script>
function middleware1(store) {
  return function(next) {
    return function(action) {
      console.log('A middleware1 开始');
      next(action)
      console.log('B middleware1 结束');
    };
  };
}

function middleware2(store) {
  return function(next) {
    return function(action) {
      console.log('C middleware2 开始');
      next(action)
      console.log('D middleware2 结束');
    };
  };
}

function middleware3(store) {
  return function(next) {
    return function(action) {
      console.log('E middleware3 开始');
      next(action)
      console.log('F middleware3 结束');
    };
  };
}

function reducer(state, action) {
  if (action.type === 'MIDDLEWARE_TEST') {
    console.log('======= G =======');  
  }
  return {};
}

var store = Redux.createStore(
  reducer,
  Redux.applyMiddleware(
    middleware1,
    middleware2,
    middleware3
  )
);

store.dispatch({ type: 'MIDDLEWARE_TEST' });
</script>
</body>
</html>

output:
A middleware1 开始
C middleware2 开始
E middleware3 开始
======= G =======
F middleware3 结束
D middleware2 结束
B middleware1 结束

            --------------------------------------
            |            middleware1              |
            |    ----------------------------     |
            |    |       middleware2         |    |
            |    |    -------------------    |    |
            |    |    |  middleware3    |    |    |
            |    |    |                 |    |    |
          next next next  ———————————   |    |    |
dispatch  —————————————> |  reducer  | — 收尾工作->|
nextState <————————————— |     G     |  |    |    |
            | A  | C  | E ——————————— F |  D |  B |
            |    |    |                 |    |    |
            |    |    -------------------    |    |
            |    ----------------------------     |
            --------------------------------------


顺序 A -> C -> E -> G -> F -> D -> B
    \---------------/   \----------/
            ↓                ↓
      更新 state 完毕      收尾工作

Koa2 的中间件

const Koa = require('koa');
const app = new Koa();


app.use(async (ctx, next)=> {
  console.log('A middleware1 开始')
  await next();
  console.log('B middleware1 结束')
});

app.use(async (ctx, next)=> {
  console.log('C middleware2 开始')
  await next();
  console.log('D middleware2 结束')
});

app.use(async (ctx, next)=> {
  console.log('E middleware3 开始')
  await next();
  console.log('F middleware3 结束')
});

app.use(async (ctx, next)=> {
  console.log('======= G =======')
});

app.listen(3000)

output:
A middleware1 开始
C middleware2 开始
E middleware3 开始
======= G =======
F middleware3 结束
D middleware2 结束
B middleware1 结束

Redux 与 Express、Koa 的中间件执行流程一致

posted @ 2016-11-01 14:00  晴明桑  阅读(1535)  评论(0编辑  收藏  举报