使用中介軟體和下一個回撥
Express 將 next
回撥傳遞給每個路由處理程式和中介軟體函式,這些函式可用於破壞跨多個處理程式的單個路由的邏輯。在沒有引數的情況下呼叫 next()
會告訴 express 繼續使用下一個匹配的中介軟體或路由處理程式。使用錯誤呼叫 next(err)
將觸發任何錯誤處理程式中介軟體。呼叫 next('route')
將繞過當前路由上的任何後續中介軟體並跳轉到下一個匹配路由。這允許將域邏輯分離為可重用的元件,這些元件是獨立的,更易於測試,更易於維護和更改。
多條匹配路線
對/api/foo
或/api/bar
的請求將執行初始處理程式以查詢成員,然後將控制權傳遞給每個路由的實際處理程式。
app.get('/api', function(req, res, next) {
// Both /api/foo and /api/bar will run this
lookupMember(function(err, member) {
if (err) return next(err);
req.member = member;
next();
});
});
app.get('/api/foo', function(req, res, next) {
// Only /api/foo will run this
doSomethingWithMember(req.member);
});
app.get('/api/bar', function(req, res, next) {
// Only /api/bar will run this
doSomethingDifferentWithMember(req.member);
});
錯誤處理程式
錯誤處理程式是具有簽名 function(err, req, res, next)
的中介軟體。它們可以按路由設定(例如 app.get('/foo', function(err, req, res, next)
),但通常,呈現錯誤頁面的單個錯誤處理程式就足夠了。
app.get('/foo', function(req, res, next) {
doSomethingAsync(function(err, data) {
if (err) return next(err);
renderPage(data);
});
});
// In the case that doSomethingAsync return an error, this special
// error handler middleware will be called with the error as the
// first parameter.
app.use(function(err, req, res, next) {
renderErrorPage(err);
});
中介軟體
上述每個函式實際上都是一箇中介軟體函式,只要請求與定義的路由匹配就會執行,但是可以在單個路由上定義任意數量的中介軟體函式。這允許在單獨的檔案和通用邏輯中定義中介軟體,以便在多個路由上重用。
app.get('/bananas', function(req, res, next) {
getMember(function(err, member) {
if (err) return next(err);
// If there's no member, don't try to look
// up data. Just go render the page now.
if (!member) return next('route');
// Otherwise, call the next middleware and fetch
// the member's data.
req.member = member;
next();
});
}, function(req, res, next) {
getMemberData(req.member, function(err, data) {
if (err) return next(err);
// If this member has no data, don't bother
// parsing it. Just go render the page now.
if (!data) return next('route');
// Otherwise, call the next middleware and parse
// the member's data. THEN render the page.
req.member.data = data;
next();
});
}, function(req, res, next) {
req.member.parsedData = parseMemberData(req.member.data);
next();
});
app.get('/bananas', function(req, res, next) {
renderBananas(req.member);
});
在此示例中,每個中介軟體函式都可以位於其自己的檔案中,也可以位於檔案中其他位置的變數中,以便可以在其他路徑中重複使用。