我们是如何使用express的中间件的呢?
代码
const express = require('express')
const app = express()
const http = require('http')
app.use(middleware)
const server = http.createServer(app())
server.listen(8000,()=>{
console.log('server run 8000')
})
// 我们来写一个
class App{
constructor(){
this.middlewareList=[]
}
use(middleware){
this.middlewareList.push(middleware)
}
compose(){
this.middlewareList.forEach(middleware=>{
//依次执行middleaware
middleware()
})
}
init(){
return (req,res)=>{
this.compose()
}
}
}
const app = new App()
const http = require('http')
app.use(middleware)
const server = http.createServer(app.init())
server.listen(8000,()=>{
console.log('server run 8000')
})
这样操作一看还是可以的,但是最重要的异步我们却没办法处理
所以,我们可以创建primise链条来进行所有中间件的连接
需求很简单。访问
/ === middleware1 返回index.html文件
/list === middleware2 返回一个简单的字符串
// index.js
const App = require('./app')
const app = new App()
const http = require('http')
const middleware1 = require('./middleware1')
const middleware2 = require('./middleware2')
app.use(middleware1)
app.use(middleware2)
const server = http.createServer(app.init((req, res) => {
// 执行最终的回调
const endData = res.getHtml ? res.getHtml : res.getList
res.end(endData)
}))
server.listen(8000, () => {
console.log('server run in 8000')
})
// app.js
module.exports = class App {
constructor() {
this.middlewareChain = Promise.resolve()
this.middlewareList = []
}
use(middleware) {
// 创建中间件list
this.middlewareList.push(middleware)
}
compose(req, res) {
this.middlewareList.forEach((middleware) => {
// 连接中间件
this.middlewareChain = this.middlewareChain.then(() => {
// 传递上下文到中间件
// 中间件执行之后每个中间件都是类似new Promise((res,rej)=>{...// to do })
return middleware(req, res)
})
})
return this.middlewareChain
}
init(callback) {
return (req, res) => {
// 启动中间件
this.compose(req, res).then(() => {
// 回调
callback(req, res)
}).catch(() => {
res.end('<h1 style="color:red;">request error</h1>')
})
}
}
}
// 中间件1 middleware 1
const fs = require('fs')
const path = require('path')
module.exports = (req, res) => {
console.log('hello world')
return new Promise((resolve, reject) => {
if (req.url === '/') {
const filePath = path.resolve(__dirname, './index.html')
fs.readFile(filePath, 'utf-8', (err, data) => {
res.getHtml = data
resolve()
})
}
})
}
// middleware2
module.exports = (req, res) => {
return new Promise((resolve, reject) => {
console.log(req.url === '/list', '====')
if (req.url === '/list') {
res.getList = '<h1>middleware2</h1>'
resolve()
} else {
resolve()
}
})
}