-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddle.js
100 lines (87 loc) · 2.15 KB
/
middle.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const http = require('http')
const slice = Array.prototype.slice
class LikeExpress {
constructor() {
// 存放中间件的列表
this.routes = {
all: [], // app.use(...)
get: [], // app.get(...)
post: [] // app.post(...)
}
}
register(path) {
const info = {}
if(typeof path === 'string') {
info.path = path
// 从第二个参数开始, 转换为数组, 存入 stack
info.stack = slice.call(arguments, 1)
} else {
info.path = '/'
// 从第一个参数开始, 转换为数组, 存入 stack
info.stack = slice.call(arguments, 0)
}
return info
}
use() {
const info = this.register.apply(this, arguments)
this.routes.all.push(info)
}
get() {
const info = this.register.apply(this, arguments)
this.routes.get.push(info)
}
post() {
const info = this.register.apply(this, arguments)
this.routes.post.push(info)
}
match(method, url) {
let stack = []
if(url === '/favicon.ico') {
return stack
}
// 获取 routes
let curRoutes = []
curRoutes = curRoutes.concat(this.routes.all)
console.log(curRoutes)
curRoutes = curRoutes.concat(this.routes[method])
curRoutes.forEach(routeInfo => {
if(url.indexOf(routeInfo.path) === 0) {
stack = stack.concat(routeInfo.stack)
}
})
return stack
}
// 核心的next机制
handle(req, res, stack) {
const next = () => {
// 拿到第一个匹配的中间件
const middleware = stack.shift()
if(middleware) {
// 执行中间件函数
middleware(req, res, next)
}
}
next()
}
callback() {
return (req, res) => {
res.json = (data) => {
res.setHeader('Content-type', 'application/json')
res.end(
JSON.stringify(data)
)
}
const url = req.url
const method = req.method.toLowerCase()
const resultList = this.match(method, url)
this.handle(req, res, resultList)
}
}
listen(...args) {
const server = http.createServer(this.callback())
server.listen(...args)
}
}
module.exports = () => {
return new LikeExpress()
}