欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Express框架Router?Route?Layer對象使用示例詳解

 更新時(shí)間:2023年03月24日 14:36:07   作者:喬治_x  
這篇文章主要為大家介紹了Express框架Router?Route?Layer對象使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

這使用倒敘的方式: 將 Layer 放在最前面講解,然后是 Route 路由項(xiàng)目,最后是 Router 路由器。

Layer

Layer 是什么? Express 中最小的存儲單元,存儲的重要內(nèi)容包括 handle 也就是 fn、path 等路徑。fn 就是中間件處理函數(shù)。重要的是 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

看看哪些的內(nèi)容實(shí)例化了 Layer 的構(gòu)造函數(shù)。Layer 的最主要的作用就是,被路由匹配到,然后取出 handle 函數(shù)最后調(diào)用,消費(fèi) handle 函數(shù)。

  • Route

一個(gè) Route 的棧 stack 中,可以存放多個(gè) 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 函數(shù),使用 Layer 構(gòu)造函數(shù)實(shí)例化 layer, 然后將 layer 壓到 stack 中保存卡里,方便以后匹配。

  • layer 的匹配方法
function matchLayer(layer, path) {
  try {
    return layer.match(path);
  } catch (err) {
    return err;
  }
}

從上面的代碼中知道,layer 對象的 match 方法,根據(jù)路徑進(jìn)行匹配, match 返回 boolean. 在匹配的時(shí)候主要處理了兩個(gè)屬性:

this.params = undefined;
this.path = undefined;

接下來看 matchLayer 函數(shù), matchLayer 調(diào)用在 Router.handle 函數(shù)的 next 函數(shù)中。

Route

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() {/*...*/}
// 擴(kuò)展 methods 包中的方法

Router

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) {/*...*/}
// 擴(kuò)展 methods + all 上所有的方法

注意: Router.handle 函數(shù).

var stack = self.stack;
while (match !== true && idx < stack.length) {/*...*/}

在 while 循環(huán)中,使用 idx 中取出 layer 和 path然后交給 matchLayer 函數(shù), 得到匹配結(jié)果。如果調(diào)用的內(nèi)容正常:

layer.handle_request(req, res, next) // 最終會得到中間件的處理函數(shù)

接下來盤點(diǎn), Router/Route/Layer 的常用方法

方法統(tǒng)計(jì)

  • Router
Router 方法說明
Router param參數(shù)
Router handle處理函數(shù)
Router process_params處理參數(shù)
Router use中間件
Router route路由
Router [methods]/all各種方法
  • Route
Route 方法說明
Route _handles_method私有處理函數(shù)
Route _options私有選項(xiàng)
Route dispatch派發(fā)請求和響應(yīng)
Route all各種方法
Route [methods]各種方法
  • Layer
Layer 方法說明
Layer handle_error處理錯(cuò)誤
Layer handle_request處理請求
Layer match根據(jù)路徑匹配路由并返回 boolean

看 Router 和 Route 有相同的方法: all/[methods]。使用 Router.route 的方法通過 path 方法關(guān)聯(lián)。同時(shí) 咋 Router.route 中實(shí)例化 Layer ,然后將 layer 保存在 Router 的 stack 中。

兩個(gè) stack

從上面的分析中,知道了 Router 中有 stack,Route 中也有 stack, 在 stack 中添加內(nèi)容(也就是 Layer)一般都是與路由和中間件相關(guān)。

  • Router 的 use 方法中,包含了實(shí)例化 Layer, 并存儲在 Router 級別的 stack 中。
  • Router 的 route 中,實(shí)例化了 Layer, 并存儲在 Router 級別的 stack 中。
  • Router 的 [methods]/all 方法中,調(diào)用了 route 方法,自然也存儲了 stack

取出 stack 中 layer

取出 Layer 發(fā)生在 Route 的 dispatch 函數(shù) 的 next 函數(shù)中,此時(shí)需要調(diào)用 layer 中匹配到的參數(shù)。

從 Router 到 layer 的路徑

  • Router 是被 express 單獨(dú)的輸出出去的。
  • Router 實(shí)例化之后,可以調(diào)用 use/[methods] 實(shí)例化 Layer 并保存 stack 中,當(dāng)然也可調(diào)用 Router.route 方法。

Router.route 方法中的 dispatch

var layer = new Layer(path, {
    sensitive: this.caseSensitive,
    strict: this.strict,
    end: true
}, route.dispatch.bind(route));

route.dispatch 在此處 bind 綁定,此時(shí)作為 Layer 構(gòu)造函數(shù)的第三個(gè)參數(shù),保存為 handle, 最后會被拿出調(diào)用。此時(shí)就進(jìn)入了 next 函數(shù)調(diào)用階段。

next 函數(shù)

next 函數(shù)是 Express 中間件的基礎(chǔ),dispatch 函數(shù)從 當(dāng)前的 stack 中拿出 layer 的實(shí)際情況調(diào)用 layer 不同的方法。

if (layer.method && layer.method !== method) {
  next(err)
}

當(dāng) layer 中的方法或者等于但當(dāng)前的方法時(shí),調(diào)用自己,此時(shí) next 函數(shù)發(fā)生了遞歸。否則進(jìn)入 handle 相關(guān)方法處理請求和處理錯(cuò)階段,此時(shí) next 方法發(fā)生了遞歸調(diào)用。

小結(jié)

  • Router -> Route -> Layer
  • Router -> use -> Layer
  • Router 和 Route 都有自己 stack 存儲 layer
  • next 函數(shù)在 Route 的 dispatch 被執(zhí)行,并在 layer 相關(guān)屬性中發(fā)生 next 函數(shù)的遞歸,實(shí)現(xiàn)了 Express 的中間件。

以上就是Express框架Router Route Layer對象使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Express使用Router Route Layer的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論