var connect = require('./connect');
var cnt =
connect()
.use(function (req, res) {
res.end('hello word\n')
})
.listen(3000);
- connect() 執(zhí)行后:生成app函數(shù)及app下掛載的幾個(gè)方法:
function app(req, res, next) {
app.handle(req, res, next);
}
app.handle = function xxx
app.use = function(route, fn)
app.route = ‘/’
app.stack = []
- .use(route, func)
path 保存路徑
handle 保存處理函數(shù)
對(duì)傳入的參數(shù)進(jìn)行判斷
if route == ‘/aaaa/’
則 route.slice(0, -1) 處理成 ‘/aaa’
結(jié)果:
path: ‘/aaa’
handle: undefined
if route != ‘string’
結(jié)果
path: ‘/’
handle: route
將每個(gè)use的配置保存到app.stack中侨嘀,即成為一種中間件量瓜,當(dāng)請(qǐng)求到達(dá)后脯颜,根據(jù)是否手動(dòng)調(diào)用next順序執(zhí)行handle:
app.stack.push(
{
path,
handle
}
)
- listen()
http.createServer啟動(dòng)server
http.createServer(
function app(req, res, next) {
app.handle(req, res, next);
}
)
每個(gè)請(qǐng)求都會(huì)依次遍歷stack中的handle蝉绷,根據(jù)route篩選符合條件的請(qǐng)求,并執(zhí)行
當(dāng)請(qǐng)求進(jìn)來(lái)后:執(zhí)行app.handle(req, res, next)多望,此時(shí)next為undefined
每個(gè)請(qǐng)求的所有內(nèi)容都在app.handle()這個(gè)閉包里剧蹂。
index 用于記錄當(dāng)前正在處理第幾個(gè)handle
protohost 根據(jù)url拿到host
removed
slashAdded
stack 所有的中間件函數(shù)
req.originUrl = req.url 存儲(chǔ)url
執(zhí)行next()
next中的邏輯:
if(skip this layer if the route doesn't match)next()進(jìn)入下一個(gè)stack
// eg: url: /foo
route: / ‘’
匹配成功
if (route match does not border "/", ".", or end) next()進(jìn)入下一個(gè)stack
// eg: url: /foo/ /foo.xxx /foo
route: /foo
匹配成功
trim off the part of the url that matches the route
請(qǐng)求進(jìn)入 -> 自調(diào)用next()執(zhí)行第1個(gè)stack里的handle -> 遇到next()執(zhí)行第2個(gè)handle -> … -> 遇到next()執(zhí)行第n個(gè)handle -> 執(zhí)行第n個(gè)handle的剩余部分 -> … -> 第二個(gè)handle的剩余部分 -> 第一個(gè)handle的剩余部分
執(zhí)行app.handle(),如果use中的函數(shù)參數(shù)為req, res, next并且無(wú)異常,需要手動(dòng)調(diào)用next醒串,否則不會(huì)到下一個(gè)use中执桌。