当前位置:网站首页>Implementing Express middleware principles
Implementing Express middleware principles
2022-08-08 03:34:00 【Can't learn Hello World】
实现Express中间件原理
一、定义一个Express class
class Express {
constructor() {
// Storage routing middleware 此处只演示get、post方法
this.routes = {
all: [],
get: [],
post: [],
}
}
二、基本的use、get、post方法
1、registerMethods help registered middleware
/** * For instance when callinguse、get、postThe methods such as registered middleware(处理路径) */
register(path) {
/** * 可能传入多个参数,At the same time, the first parameter can be a request path,To deal with the path */
const info = {
}
if (typeof path === "string") {
/** * If the first parameter passed in is a path to intercept a first parameter outside of the parameters as middleware in the */
info.path = path
info.middleware = slice.call(arguments, 1)
} else {
/** * If the first parameter no afferent path is the default an'/'根路径,That all requests will be through the middleware processing */
info.path = "/"
info.middleware = slice.call(arguments, 0)
}
return info
}
2、方法实现
/** * Registered in all callsuseRegistered or routing method to performregisterHelp with parameter and register */
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)
}
三、listenThe realization of a monitor request
1、listen方法
listen(...args) {
const server = http.createServer(this.callback())
server.listen(...args)
}
2、listen方法依赖的callback
callback() {
return (req, res) => {
/** * 模拟实现res.json,方便测试 */
res.json = (data) => {
res.setHeader("Content-Type", "application/json")
res.end(JSON.stringify(data))
}
// 根据method和urlMatching the corresponding routing, and middleware
const {
url, method } = req
const middlewareList = this.matchMiddleware(url, method)
// The match to the middleware tomiddlewareHandler执行
this.middlewareHandler(middlewareList)
}
}
3、The realization of the matching routing middleware and middleware execution
1、matchMiddleware匹配中间件
/** * Match the specified request routing, and middleware * @param {请求的路径} url * @param {请求的方法} method */
matchMiddleware(url, method) {
let middlewareList = []
if (url === "/favicon.ico") {
return middlewareList
}
/** * To match the request firstmethod */
method = method.toLowerCase()
const currentRoutes = [...this.routes.all, ...this.routes[method]]
/** * According to the request path matching */
middlewareList = currentRoutes.map((route) => {
if (route.path.indexOf(url) === 0) {
return route.middleware
}
})
return middlewareList
}
2、middleHandlerMiddleware execution method
middlewareHandler(req, res, middlewareList) {
const next = () => {
// Remove the first middleware
const middleware = middlewareList.shift()
// Execute the middleware functions,
//并传入next,When the middleware implement thenextFunction will then get to the next middleware,
//And so on indefinitely,Then realized the middleware execution in turn
middleware(req, res, next)
}
// For the first time introduced into middleware,马上执行
next()
}
四、完整代码
const http = require("http")
const slice = Array.prototype.slice
class Express {
constructor() {
// Storage routing middleware 此处只演示get、post方法
this.routes = {
all: [],
get: [],
post: [],
}
}
/** * For instance when callinguse、get、postThe methods such as registered middleware(处理路径) */
register(path) {
/** * 可能传入多个参数,At the same time, the first parameter can be a request path,To deal with the path */
const info = {
}
if (typeof path === "string") {
/** * If the first parameter passed in is a path to intercept a first parameter outside of the parameters as middleware in the */
info.path = path
info.middleware = slice.call(arguments, 1)
} else {
/** * If the first parameter no afferent path is the default an'/'根路径,That all requests will be through the middleware processing */
info.path = "/"
info.middleware = slice.call(arguments, 0)
}
return info
}
/** * Registered in all callsuseRegistered or routing method to performregisterHelp with parameter and register */
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 the specified request routing, and middleware * @param {请求的路径} url * @param {请求的方法} method */
matchMiddleware(url, method) {
let middlewareList = []
if (url === "/favicon.ico") {
return middlewareList
}
/** * To match the request firstmethod */
method = method.toLowerCase()
const currentRoutes = [...this.routes.all, ...this.routes[method]]
/** * According to the request path matching */
middlewareList = currentRoutes.map((route) => {
if (route.path.indexOf(url) === 0) {
return route.middleware
}
})
return middlewareList
}
middlewareHandler(req, res, middlewareList) {
const next = () => {
// Remove the first middleware
const middleware = middlewareList.shift()
// Execute the middleware functions,
//并传入next,When the middleware implement thenextFunction will then get to the next middleware,
//And so on indefinitely,Then realized the middleware execution in turn
middleware(req, res, next)
}
// For the first time introduced into middleware,马上执行
next()
}
callback() {
return (req, res) => {
/** * 模拟实现res.json,方便测试 */
res.json = (data) => {
res.setHeader("Content-Type", "application/json")
res.end(JSON.stringify(data))
}
// 根据method和urlMatching the corresponding routing, and middleware
const {
url, method } = req
const middlewareList = this.matchMiddleware(url, method)
// The match to the middleware tomiddlewareHandler执行
this.middlewareHandler(middlewareList)
}
}
listen(...args) {
const server = http.createServer(this.callback())
server.listen(...args)
}
}
module.exports = () => {
return new Express()
}
总结
The important mechanism of middleware is first registered,Then how to execute the middleware andnext()的实现,如何借助next()To control the various links between the middleware,Here I mainly depends on themiddleHandler方法的实现.
边栏推荐
猜你喜欢
随机推荐
PC博物馆(番外01)-城会玩,初中生开发实体尺规大航海游戏
Knowledge of DisplayPort-DP interface
NVIDIA NCCL Optimization - Leverage shared memory for faster collective communication than NCCL
The live broadcast of agricultural products continues to heat up, Economic Daily: Don’t forget quality when rushing
KDD'22 | CausalMTA: 基于因果推断的无偏广告多触点归因技术
Video Signal Loss Detection Based on Image 2D Entropy (Signal Loss Detection)
新手使用 go channel 需要注意的问题
音视频基础
SQL 2016 如何跟踪是哪个存储或语句导致记录表中记录被修改了
Spark基础【RDD分区和并行度】
The project management process and key points for each link
【保研面试】英文问题
After nibbling on this Ali manual, the new year will enter Ali from seven sides
06 tp6 的数据更新(改)及删除 《ThinkPHP6 入门到电商实战》
测试岗电话面试——必问题型
RV-GAN: Segmentation of retinal vascular structures in fundus photographs using a novel multi-scale generative adversarial network
The impact of rays on performance in three.js
egg-阿里云短信配置
Embedded Interview Questions
杭电多校6 1009. Map









