express初識源碼-Router,Layer,Route

express提供豐富的http工具,快速處理請求,響應。核心功能中間件,路由,基於三個類來實現,Router,Layer,Route。javascript

1.Router

主要核心內容:java

  • stack數組存放子路由,中間件。
  • handle方法,循環stack數組,根據規則執行響應回調函數。

通常添加一個路由會這樣寫代碼:express

app.get('/list', function (req, res) {
		res.end('hello express');
	});
複製代碼

在Router裏面作了一件事來支持這樣的寫法:數組

var methods = require('methods');  //包含http的方法名
	
	methods.forEach((methods) => {
		//拿到具體一個方法名 methods
		Router.prototype[methods] = function() {
			// 調用route方法往stack裏面push一個路由
		}
	})
複製代碼

express中路由和中間件都是放在了stack數組裏面,那麼就有順序問題,若是use一箇中間件那麼須要放在路由前面。app

const express = require('express');
	const app = new express();
	
	app.use((req, res, next) => {
	    console.log('111');
	    next();
	});
	
	app.get('/list',(req, res) => {
	    res.end('hello express');  
	});
	
	app.listen('8000');
複製代碼

next表示經過,能夠執行下箇中間件或路由,若是發生錯誤,則能夠拋出錯誤,交給錯誤中間件處理,錯誤中間件接受4個參數,4個參數的use就表明了錯誤中間件.第一個參數爲錯誤信息函數

app.use((req, res, next) => {
	    console.log('111');
	    next(new Error('error'));
	});
	
	app.use((error, req, res, next) => {
	    console.log(error);
	})
複製代碼

當請求來時,會執行handle,循環stack,發現path相同,method相同,那麼調用對應callback。這樣處理,帶來了一個問題,若是路由不斷增多,stack數組會不斷增大,匹配效率降低,爲了提升效率,express引入了route,layer.工具

2.Layer

把同一個path造成一層,並提供match方法進行匹配判斷,handle方法來執行當前層的深刻匹配methods。post

簡單理解就是匹配一個路徑,而後執行回調方法。ui

那麼當一個路由註冊的時候,則新生成一個Layer實例,若是剩下還有路由路徑相同,則放在該層。怎麼去放入這層的,在Route作。this

3.Route

Layer造成了層,但沒有作匹配methods的事情,那麼這個事情由Route來作。在Layer裏面會傳入一個handle方法,那麼這個handle方式就是Route裏面的dipatch方法,當Layer的路徑已經匹配成功,就會交給Route來匹配method,Route的對象存放全部註冊的方法名,用於快速匹配是否有註冊該方法,在Route裏面又複用了Layer,去執行真正回調處理函數。

4.實現高效率匹配

app.route('/list').get((req, res) => {
		res.end('hello get');  
	}).post((req, res) => {
		res.end('hello post');  
	}).put((req, res) => {
		res.end('hello put');
	}).delete((req, res) => {
		res.end('hello delete');
	});
複製代碼

下面看一個僞代碼,看如何去實現的app.route方法:

app.route = function(path) {
		const route = new Route(path); // 生成一個route實例
		const Layer = new Layer(path, route.dispatch.bind(route)); // 把route裏面的dispatch方法做爲Layer的處理函數
		
		this.stack.push(layer); // 放入數組中
		
		return route; // 返回route實例,用於鏈式調用,去註冊method方法
	}
複製代碼
相關文章
相關標籤/搜索