node的中间件

本文探讨了Node.js中的中间件概念,它用于封装Http请求处理的细节,如日志记录、IP过滤、参数验证等。中间件通过简化基础设施与业务逻辑之间的交互,帮助开发者专注于业务开发。文中介绍了中间件的基本形式及其异步操作处理,同时讨论了如何在业务处理前后执行中间件,特别是对于需要在业务处理后执行的情况,如统计时间的日志中间件的实现策略。
摘要由CSDN通过智能技术生成

在nodeJS中,中间件主要是指封装所有Http请求细节处理的方法,一次Http请求通常包含很多工作:如记录日志,IP过滤,查询字符串、请求体解析,cookie处理、权限验证、参数验证、异常处理等、但对web应用而言,并不希望接触到这么多细节性的处理,因此使用中间件来简化及隔离这些基础设施与业务逻辑之间的细节,让开发者更关注在业务的开发上,他的工作模式如下:

中间件机制核心实现

中间件是从Http请求发起到响应结束过程中的处理方法,通常需要对请求和响应进行处理,因此一个基本的中间件的形式如下:

const middleware = (req, res, next) => {
  // TODO
  next()
}

 模拟最基本的中间件

// 定义简单的三个中间件
      const httpMeth1 = (req, res, next) => {
        console.log('我是请求1')
        next()
      }
      const httpMeth2 = (req, res, next) => {
        console.log('我是请求2')
        next()
      }
      const httpMeth3 = (req, res, next) => {
        console.log('我是请求3')
        next()
      }
      // 中间件数组
      const allHttpMeth = [httpMeth1, httpMeth2, httpMeth3]
      function run (req, res) {
        const next = () => {
          // 获取中间件
          const allHttpMethitem = allHttpMeth.shift()
          if (allHttpMethitem) {
            // 执行
            allHttpMethitem(req, res, next)
          }
        }
        next()
      }
      run() // 模拟请求发起

如果中间件中有异步操作,需要在异步操作的流程结束后再调用next()方法,否则中间件不能按顺序执行

 const httpMeth3 = (req, res, next) => {
        // 如果中间件中有异步操作,需要在异步操作完成后再调用next
        new Promise((resolve, reject) => {
          console.log('我是请求3')
        }).then(() => {
          next()
        })
      }

    有些中间件不止需要在业务处理前执行,还需要在业务处理后执行,比如统计时间的日志中间件。在方式一情况下,无法在next()为异步操作时再将当前中间件的其他代码作为回调执行。因此可以将next()方法的后续操作封装成一个Promise对象,中间件内部就可以使用next.then()形式完成业务处理结束后的回调。改写run()方法如下:

 // 定义简单的三个中间件
      const httpMeth1 = (req, res, next) => {
        return next().then((res) => {
          console.log('我是请求1')
        })
      }
      const httpMeth2 = (req, res, next) => {
        return next().then((res) => {
          console.log('我是请求2')
        })
      }
      const httpMeth3 = (req, res, next) => {
        // 如果中间件中有异步操作,需要在异步操作完成后再调用next
        /* new Promise((resolve, reject) => {
           console.log('我是请求3')
         }).then(() => {
           next()
         }) */
        return next().then((res) => {
          console.log('我是请求3')
        })
      }
      // 中间件数组
      const allHttpMeth = [httpMeth1, httpMeth2, httpMeth3]
      function run (req, res) {
        const next = () => {
          // 获取中间件
          const allHttpMethitem = allHttpMeth.shift()
          if (allHttpMethitem) {
            // 执行
            return Promise.resolve(allHttpMethitem(req, res, next))
          } else {
            return Promise.resolve('结束')
          }
        }
        next()
      }
      run() // 模拟请求发起
    }
async await 实现
  // 定义简单的三个中间件
      const httpMeth1 = (req, res, next) => {
        return next().then((res) => {
          console.log('我是请求1')
        })
      }
      // 也可以用 async
      const httpMeth2 = async (req, res, next) => {
        console.log('我是请求2')
        let result = await next()
        console.log('2', result)
        return 'httpMeth2 end'
      }
      const httpMeth3 = (req, res, next) => {
        // 如果中间件中有异步操作,需要在异步操作完成后再调用next
        /* new Promise((resolve, reject) => {
           console.log('我是请求3')
         }).then(() => {
           next()
         }) */
        return next().then((res) => {
          console.log('我是请求3')
        })
      }
      // 中间件数组
      const allHttpMeth = [httpMeth1, httpMeth2, httpMeth3]
      function run (req, res) {
        const next = () => {
          // 获取中间件
          const allHttpMethitem = allHttpMeth.shift()
          if (allHttpMethitem) {
            // 执行
            return Promise.resolve(allHttpMethitem(req, res, next))
          } else {
            return Promise.resolve('结束')
          }
        }
        next()
      }
      run() // 模拟请求发起
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值