简单模拟express中间件

const http = require('http')
let slice = Array.prototype.slice

class express{
  constructor(){
    this.routes={
      all:[],//用于储存app.use()方法注册的中间件
      get:[],//用于储存app.get()方法注册的中间件
      post:[]//用于储存app.post()方法注册的中间件
    }
  }
  register(path){
    //判断注册的参数个数
    let info={}//存储每一次注册的信息
    if(typeof path === 'string'){
      info.path = path//注册路径
//如果是带有路由string的参数注册,那么就要将第一个路由参数截去,剩下的才是中间件参数
      info.stack = slice.call(arguments,1)
    }else{
      info.path ='/'
//如果不带就不用截取
      info.stack = slice.call(arguments,0)//存储中间件参数数组
    }
    return info
  }

  use(){
    const info = this.register.apply(this,arguments)
//argument获得的就是中间件参数列表
    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(url,method){
    let stack = []//中间件堆放栈
    if(url === '/favicon.ico'){
      return stack//浏览器自带请求直接返回
    }

    let curRoutes = []
    curRoutes = curRoutes.concat(this.routes.all)
    curRoutes = curRoutes.concat(this.routes[method])

    curRoutes.forEach(item=>{
      if(url.indexOf(item.path)===0){
//检测是不是浏览器中输入url的父级路径,如果是就将符合条件的中间件放入栈中
        stack = stack.concat(item.stack)
      }
    })
    return stack
  }

  
  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)
          )
      }//express中的res.json方法
      const url = req.url
      const method = req.method.toLowerCase()

      const resultList = this.match(url,method)//根据路由来匹配中间件是否执行
      this.handle(req, res, resultList)
  }
    
  }
  listen(...args){//监听端口
    let server = http.createServer(this.callback())//回调函数
    server.listen(...args)
  }
}

module.exports = ()=>{
  return new express()
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值