您好,登錄后才能下訂單哦!
今天小編給大家分享一下Express框架Router、Route和Layer對象如何使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
Layer 是什么? Express 中最小的存儲單元,存儲的重要內容包括 handle 也就是 fn、path 等路徑。fn 就是中間件處理函數。重要的是 route 中能匹配:
module.exports = Layer; function Layer(path, options, fn) { if (!(this instanceof Layer)) { return new Layer(path, options, fn); } var opts = options || {}; this.handle = fn; this.name = fn.name || '<anonymous>'; this.params = undefined; this.path = undefined; this.regexp = pathRegexp(path, this.keys = [], opts); this.regexp.fast_star = path === '*' this.regexp.fast_slash = path === '/' && opts.end === false } Layer.prototype.handle_error = function handle_error(error, req, res, next) {} Layer.prototype.handle_request = function handle(req, res, next) {} Layer.prototype.match = function match(path) {} // 返回 boolean
看看哪些的內容實例化了 Layer 的構造函數。Layer 的最主要的作用就是,被路由匹配到,然后取出 handle 函數最后調用,消費 handle 函數。
Route
一個 Route 的棧 stack 中,可以存放多個 Layer。
Route.prototype.all = function all() { /**/ var layer = Layer('/', {}, handle); /**/ } Route.prototype[method] = function(){ /**/ var layer = Layer('/', {}, handle); /**/ }
Router 中
proto.route = function route(path) { // *** var layer = new Layer(path, { sensitive: this.caseSensitive, strict: this.strict, end: true }, route.dispatch.bind(route)); // *** this.stack.push(layer); };
proto.use = function use(fn) { var layer = new Layer(path, { sensitive: this.caseSensitive, strict: false, end: false }, fn); this.stack.push(layer); }
在 Router 中的 route 和 use 函數,使用 Layer 構造函數實例化 layer, 然后將 layer 壓到 stack 中保存卡里,方便以后匹配。
layer 的匹配方法
function matchLayer(layer, path) { try { return layer.match(path); } catch (err) { return err; } }
從上面的代碼中知道,layer 對象的 match 方法,根據路徑進行匹配, match 返回 boolean. 在匹配的時候主要處理了兩個屬性:
this.params = undefined; this.path = undefined;
接下來看 matchLayer 函數, matchLayer 調用在 Router.handle 函數的 next 函數中。
module.exports = Route; function Route(path) { this.path = path; this.stack = []; this.methods = {}; } Route.prototype._handles_method = function _handles_method(method) {/*...*/} Route.prototype._options = function _options() {/*...*/} Route.prototype.dispatch = function dispatch(req, res, done) {/*...*/} Route.prototype.all = function all() {/*...*/} // 擴展 methods 包中的方法
Router 就是 proto
var proto = module.exports = function(options) {/*...*/} proto.param = function param(name, fn) {/*...*/} proto.handle = function handle(req, res, out) {/*...*/} proto.process_params = function process_params(layer, called, req, res, done) {/*...*/} proto.use = function use(fn) {/*...*/} proto.route = function route(path) {/*...*/} // 擴展 methods + all 上所有的方法
注意: Router.handle 函數.
var stack = self.stack; while (match !== true && idx < stack.length) {/*...*/}
在 while 循環中,使用 idx 中取出 layer 和 path然后交給 matchLayer 函數, 得到匹配結果。如果調用的內容正常:
layer.handle_request(req, res, next) // 最終會得到中間件的處理函數
接下來盤點, Router/Route/Layer 的常用方法
Router
Router 方法 | 說明 |
---|---|
Router param | 參數 |
Router handle | 處理函數 |
Router process_params | 處理參數 |
Router use | 中間件 |
Router route | 路由 |
Router [methods]/all | 各種方法 |
Route
Route 方法 | 說明 |
---|---|
Route _handles_method | 私有處理函數 |
Route _options | 私有選項 |
Route dispatch | 派發請求和響應 |
Route all | 各種方法 |
Route [methods] | 各種方法 |
Layer
Layer 方法 | 說明 |
---|---|
Layer handle_error | 處理錯誤 |
Layer handle_request | 處理請求 |
Layer match | 根據路徑匹配路由并返回 boolean |
看 Router 和 Route 有相同的方法: all/[methods]。使用 Router.route 的方法通過 path 方法關聯。同時 咋 Router.route 中實例化 Layer ,然后將 layer 保存在 Router 的 stack 中。
從上面的分析中,知道了 Router 中有 stack,Route 中也有 stack, 在 stack 中添加內容(也就是 Layer)一般都是與路由和中間件相關。
Router 的 use 方法中,包含了實例化 Layer, 并存儲在 Router 級別的 stack 中。
Router 的 route 中,實例化了 Layer, 并存儲在 Router 級別的 stack 中。
Router 的 [methods]/all 方法中,調用了 route 方法,自然也存儲了 stack
取出 Layer 發生在 Route 的 dispatch 函數 的 next 函數中,此時需要調用 layer 中匹配到的參數。
Router 是被 express 單獨的輸出出去的。
Router 實例化之后,可以調用 use/[methods] 實例化 Layer 并保存 stack 中,當然也可調用 Router.route 方法。
var layer = new Layer(path, { sensitive: this.caseSensitive, strict: this.strict, end: true }, route.dispatch.bind(route));
route.dispatch 在此處 bind 綁定,此時作為 Layer 構造函數的第三個參數,保存為 handle, 最后會被拿出調用。此時就進入了 next 函數調用階段。
next 函數是 Express 中間件的基礎,dispatch 函數從 當前的 stack 中拿出 layer 的實際情況調用 layer 不同的方法。
if (layer.method && layer.method !== method) { next(err) }
當 layer 中的方法或者等于但當前的方法時,調用自己,此時 next 函數發生了遞歸。否則進入 handle 相關方法處理請求和處理錯階段,此時 next 方法發生了遞歸調用。
以上就是“Express框架Router、Route和Layer對象如何使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。