首先说明一下需要实现那些功能
- use函数这个函数有2个参数,第一个参数是需要匹配的路径可不传,默认是匹配所有路径第二个是回调函数。
- all函数这个函数有2个参数,第一个参数是需要匹配的路径第二个参数是回调函数。
- listen函数启动监听
- get,post等常用的请求函数这些函数都有2个参数,第一个参数是需偠匹配的路径第二个参数是回调函数。
- next核心函数调用该函数时不传参则调到下一个处理函数,传参则直接跳到错误中间件
需要实现的功能代码如下:
- 初始化一个Express类并添加成员属性routes用来存放所有路由,最后用工厂模式来导出一个创建Express实例的方法
-
实现use方法,首先需要判斷调用use方法的时候传递了几个参数因为上面提到了第一个参数是需要匹配的路径,可不传默认是匹配所有路径,第二个是回调函数所以我们只需要判断第二个参数是不是一个函数,如果是则认为传递了2个参数如果不是则认为传递了一个参数。然后将该路由存储进routes中所有路由(包括后面的all,getpost的路由)在存储的时候,需要存储的是一个对象该对象包含三个字段,分别是method(用来区分是什么路由中間件路由,get路由等)path(匹配的路径),handler(处理函数)
- 实现all方法,跟上面实现use方法的差不多唯一区别就是all方法2个参数都是比传的,不需要判断是否传递了匹配路径的参数
- 实现其他请求路由方法(getpost等),由于请求的方法比较多所以不会一个一个的去初始化,这里可以利用js对象的动态属性把所有请求路由动态挂在到类中,然后在构造函数中调用
- 实现listen方法,这个方法比较简单直接调用http模块的createServer开启一個http服务即可
- 在上面实现listen方法中可以看见有一个appServer的方法,所以我们需要去实现一下appServer方法需要返回一个函数,该函数接受2个参数一个是req请求对象,一个是res响应对象然后需要把req请求对象中的请求方法和请求路径解析出来,请求路径需要通过url.parse解析出来然后就开始执行路由,吔就是是我们的核心方法next
-
next方法实现首先在执行前需要判断当前路由索引index时候等于routes的长度,等于则说明找不到对应的路由这时需要结束請求,并告诉用户找不到对应的路由然后next方法接受一个参数,若是这个参数存在则直接跳到错误中间件,由于错误中间件是必须有4个參数的所以我们可以判断routes中每个对象中handler处理函数是否有4个参数,然后直接调用即可若是参数不存在则执行下一个路由。在执行路由的時候我们需要判断当前路由是不是use中间件,因为错误中间件也是通过use方法添加进去的我们需要排除错误中间件。
- 最后我们回到init方法Φ,创建一个默认的前置中间件在req请求对象上挂在一些属性,如querypathname,hostname等等属性,init方法变成如下:
一个简易版的express就这样完成了express的实现核心還是在next方法上,其他的一些方法如use、all等都是往routes中存放一个对象。最后贴上一个完整的代码
}