[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 的中间件执行流程一致