自我封装Node Express遇到的问题

199 阅读2分钟

「本文正在参与技术专题征文Node.js进阶之路,点击查看详情

今天我自己简单封装了一个Node express,有get和listen功能,我遇到了这样一个问题, 在使用http.createServer时使用Array.prototype.find()找对应的routers,找到后调用对象里面的handle函数,报错undefined

先来看看我封装的express吧!

let routers = []
class Application {
  get(path, handler) {
    routers.push({ 
      path,
      method: 'GET',
      handler
    })
  }
  listen() {
    const server = http.createServer(function(request, response) {
      const pathname = request.url
      const method = request.method
      let obj = routers.find(v => v.path == pathname && v.method == method)      
      obj.handler(request, response)  // 报错:undefined无handler
    })
    server.listen(...arguments)
  }
}

首先定义了一个routers数组,以对象的形式存储路由和它的路径、方法和处理函数

然后定义个Application类,里面有get和listen方法

get方法用来传入路由,listen方法来监听端口和调用路由的处理函数

然后我们来使用一下它。

const app = new Application()
app.get('/', (req, res) => {
  res.end('Hello World!')
})
app.listen(3400, () => {
  console.log('已监听3400端口')
})

调用之后我发现页面能显示出来,但终端报错,说undefined没有handler函数

image.png

终端报错

image.png

经过反复调试发现,每发送一次请求都会调用一次createServer中的函数,就是这部分代码。

 const server = http.createServer(function(request, response) {
   const pathname = request.url
   const method = request.method
   let obj = routers.find(v => v.path == pathname && v.method == method)
   obj.handler(request, response)
 })

发现是因为在加载时发送了两个请求,一个pathname是'/',另一个是'/favicon.ico'

image.png

因为Array.prototype.find()函数在匹配不到符合条件的元素时,会返回undefined

然后我添加了一个条件判断,最终解决了这个问题,我们来看完整的代码吧!

let routers = []
class Application {
  get(path, handler) {
    routers.push({ 
      path,
      method: 'GET',
      handler
    })
  }
  listen() {
    const server = http.createServer(function(request, response) {
      const pathname = request.url
      const method = request.method
      // 发送一次请求就会调用一次
      let obj = routers.find(v => v.path == pathname && v.method == method)      
      if(obj) obj.handler(request, response)
      else console.log(`未发现资源:${pathname}`) 
    })
    server.listen(...arguments)
  }
}
​
const app = new Application()
app.get('/', (req, res) => {
  res.end('Hello World')
})
app.listen(3400, () => {
  console.log('一监听3400');
})

有不明白的小伙伴,欢迎评论!

可以给个赞吗?小主🥺