这是渐进式Express源码学习 | 小白也能懂源码系列文章的第六篇。javascript
请结合该节代码阅读Lesson6-独孤求败java
这篇文章咱们在第五篇文章的基础上,实现一个稍微增强版的Express,功能包括git
这篇文章要实现的express的指望用法以下github
const express = require('../index.js')
const app = express()
app.get('/foo', function handle1 (req, res, next) {
next(new Error('Bang!'))
}, function handle2 (req, res, next) {
res.end('Will not go here')
}, function handle3 (err, req, res, next) {
console.log(`Error Caught! Error message is ${err.message}`)
next(err)
})
app.get('/foo', function (req, res, next) {
res.end('Will not go here too')
})
app.use('/foo', function (req, res, next) {
res.end('Will not go here too')
})
app.get('/foo', function (err, req, res, next) {
console.log(err.name)
res.end('Will not go here too')
})
app.use('/foo', function (err, req, res, next) {
console.log(`Error Caught! Error message is ${err.message}`)
res.end('Go here')
})
app.listen(3000)
复制代码
在阅读这篇文章以前,请务必了解express错误处理,例如上面的例子中,你须要知道抛出的错误是在哪一个环节捕捉的,不然阅读这个文章会吃力express
这一节,会引入两个概念,路由中间件和非路由中间件 新的章节,主要有3个变化app
首先要讲解,路由中间件和非路由中间件。路由中间件,经过app.verb添加,结构是处理函数挂载到layer上,layer推送到route上,route的dispatch函数又挂载到一个新的layer,这个layer再推送到Router的stack中。 结构相似这样函数
而对于非路由中间件,直接挂载到layer上,而后推送到Router的stack 结构是这样的学习
因此,两者结合后,结构是这样的ui
理解了上面这些,咱们看具体的代码 首先是lib/route/layer.jsspa
他们的区别是若是你的layer的fn是function(req, res, next) ,调用这个layer的handle_error会直接掉过,只有当这个layer的fn是function(err, req, res, next)才会有效
再看lib/route/route.js
注意第44行到48行,route.dispatch函数会判断是否有error,若是有,调用layer的handler_error函数,这样正常的路由就会被跳过
再看lib/route/index.js
首先是增长了一个use函数,这个函数用来增长非路由中间件,直接建立一个layer,绑定函数后推送到stack
最后,看Router.handle,咱们聚焦在next函数
看代码第55行,这个地方判断是不是路由中间件,若是layer有route属性,说明是路由中间件,不然不是。
在process_params里也是,若是有错误,调用layer.handle_error,不然调用handle_request。
本文实现了一个增强的Express。到目前为止,一个基本的Express已经实现了。和真实的Express相比,只是一些细节差别