我们知道Express中间件就是一个个的函数, 那么怎么让这些函数有序的执行呢? 那就需要我们调用 next 函数。其实 next函数调用的就是下一个中间件函数。
以下代码实现了简单的 app.use 注册中间件, 以及 get、post方式的中间件。其他请求方式的中间件实现同理
核心代码:
const next = () => { const stack = stacks.shift() if(stack) { stack(req, res, next) } } next()stacks就是一个数组队列, 存放所有符合规则的中间件函数。遵循先进先出的原则。也就是最先注册的中间件函数最先执行。
实现代码 const http = require('http') const slice = Array.prototype.slice class Express { constructor() { this.router = { all: [], // 匹配所有额中间件函数 get: [], post: [] } } /** * 这里整合中间件 * @param {string} path * @returns {object} */ middlewareHandler(path) { const info = {} if (typeof path === 'string') { info.path = path info.stack = slice.call(arguments, 1) // 中间件数组 } else { info.path = 'http://www.likecs.com/' info.stack = slice.call(arguments, 0) } return info } use() { const allStack = this.middlewareHandler(...arguments) this.router.all.push(allStack) } get() { const getStack = this.middlewareHandler(...arguments) this.router.get.push(getStack) } post() { const postStack = this.middlewareHandler(...arguments) this.router.post.push(postStack) } /** * * @param {string} method * @param {string} url * @returns {Array} */ accordStack(method, url) { let stacks = [] stacks = stacks.concat(this.router.all) stacks = stacks.concat(this.router[method]) return stacks .filter(stack => { return url.indexOf(stack.path) !== -1 }).map(item => item.stack[0]) } handler(req, res, stacks) { // 函数表达式 const next = () => { const stack = stacks.shift() if(stack) { stack(req, res, next) } } next() } callback() { return (req, res) => { res.json = data => { res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify(data)) } // 拿到请求的方法和url, 对中间件函数进行筛选 const {method, url} = req const stacks = this.accordStack(method.toLowerCase(), url) this.handler(req, res, stacks) } } listen(...args) { const server = http.createServer(this.callback()) server.listen(...args) } } // 工厂模式, 导出一个实例对象 module.exports = () => { return new Express() }