nodejs(這指express) 中間件
鋪墊:
一個請求發送到服務器,要經歷一個生命周期,服務端要: 監聽請求-解析請求-響應請求,服務器在處理這一過程的時候,有時候就很復雜了,將這些復雜的業務拆開成一個個子部分,子部分就是一個個中間件。對於處理請求來說,在響應發出之前,可以對請求和該級響應做一些操作,並且可以將這個處理結果傳遞給下一個處理步驟
express 這樣描述中間件的:
執行任何代碼。
修改請求和響應對象。
終結請求-響應循環。
調用堆棧中的下一個中間件
分類:
應用級中間件
路由級中間件
錯誤處理中間件
內置中間件
第三方中間件
舉個栗子:
var express = require('express');
var app = express();
app.get('/', function(req, res, next) {
// req 修改請求
// res 響應對象
next(); // 當前中間件函數沒有結束請求/響應循環, 調用next(),
// 將控制權傳遞給下一個中間件函數繼續往下處理,否則頁面到此會被掛起
});
app.get('/end', function(req, res) {
res.send('程序到我這里就結束了,沒有next方法');
})
app.listen(3000);
上面next()的說明: next()函數不是nodejs或者express的函數,而是傳遞中間件函數的第三變量,它是一個統稱,可以為任意名稱,為了名稱統一,不造成混淆,約定為next(),調用它之后會將調用應用程序中的下一個中間件程序
中間件的使用說明:
var express = require('express');
var app = express();
app.use(requestTime); //
var requestTime = function(req,res, next) {
req.requestTime = new Date().getTime();
next();
}
app.get('/time', function(req, res, next) {
var timeText = '當前時間為:';
timeText = timeText + req.requestTime; // 這里的req.requestTime 是上一個中間件函數傳遞過來的,
// 一個業務處理流程,多個中間件函數對請求 req進行修改處理,並且通過next() 傳遞給下一個中間件函數,
// 這樣下面的中間件函數都能拿到上一個中間件函數處理的結果
res.send(timeText);
});
app.get('/end', function(req, res) {
res.send('程序到我這里就結束了,沒有next方法');
})
app.listen(3000);
下面是多個中間件函數,在各自函數中處理請求和響應的例子:
具體
var express = require('express');
var app = express();
var middleA = function (req, res, next) {
req.useOne = '應用程序經過了 middleA ';
res.useOne = 'middleA 處理后的數據 middleA';
req.paramasQuery = 1
// console.log(req.useOne, req.useTwo, req.useThree);
next();
}
var middleB = function (req, res, next) {
req.useTwo = '應用程序又經過了 middleB';
res.useTwo = 'middleB 處理后的數據 middleB';
req.paramasQuery += 1;
console.log(res.useOne, res.useTwo, res.useThree);
next();
}
var middleC = function (req, res, next) {
req.useThree = '應用程序又經過了 middleC';
res.useThree = 'middleC 處理后的數據 middleC';
req.paramasQuery += 2;
console.log(res.useOne, res.useTwo, res.useThree);
console.log(req.paramasQuery);
next();
}
app.use(middleA);
app.use(middleB);
app.use(middleC);
app.get('/', function(req, res, next) {
console.log(req.useOne, req.useTwo, req.useThree);
// 應用程序經過了 middleA 應用程序又經過了 middleB 應用程序又經過了 middleC
// 上面的req里面的參數就是在 不同的中間件函數中處理出來的
console.log(res.useOne, res.useTwo, res.useThree);
// middleA 處理后的數據 middleA middleB 處理后的數據 middleB middleC 處理后的數據 middleC
// 上面的res的響應參數也是在上面一個個中間件的響應res中逐步處理 累加而得
req.paramasQuery += 3;
// req中paramasQuery的參數經過中間不同的中間件函數處理,已經累加到7,
// 同理對於res 采用相同的處理方式,也可以達到這樣的效果
// 我們以此可以推出,如果處理一個很復雜的程序時,我們一個中間件函數只處理一個步驟,
// 並且可以把該步驟處理后的結果,傳遞給下一個中間件函數處理,
// 一種流水線的處理方式,職責專一,效率很快
res.send('req.paramasQuery 經過不同的中間件處理后的結果是:' + req.paramasQuery); // 7
})
app.listen(5000, function() {
console.log('5000 端口啟動了')
})
總結:
express 中間件函數,幫助拆解主程序的業務邏輯,並且每一個的中間件函數處理的結果都會傳遞給下一個中間件函數。想象一下工廠上流水線工人,在清洗一個箱子的一個場景。
第一個人清洗側面,第二個人清洗底面,第三個人清洗頂面,。。。,這條流水線結束后,箱子也就清洗干凈了。
各做各的,不相互影響,又彼此協作。