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