Node 主要用在開發 Web 應用,koa 是目前 node 裡最流行的 web 框架。
在 Node 開啟一個 http 服務簡直易如反掌,官網 demo。
const http = require("http");
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.end("Hello World\n");
});
const hostname = "127.0.0.1";
const port = 3000;
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
//前端全棧學習交流圈:866109386
//面向1-3經驗年前端開發人員
//幫助突破技術瓶頸,提升思維能力
- 引入 http 模塊, http 的 createServer 方法創建了一個 http.Server 的實例。
- server 監聽 3000 端口。
- 我們傳入到 createServer 裡的函數實際是監聽 request 事件的回調,每當請求進來,監聽函數就會執行。
- request 事件的監聽函數,其函數接受兩個參數,分別是 req 和 res 。其中 req 是一個可讀流, res 是一個可寫流。我們通過 req 獲取 http 請求的所有信息,同時將數據寫入到 res 來對該請求作出響應。
koa 應用
koa 如何創建一個 server, 直接上個官網的例子
const Koa = require("koa");
const app = new Koa();
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set("X-Response-Time", `${ms}ms`);
});
// logger
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}`);
});
// response
app.use(async ctx => {
ctx.body = "Hello World";
});
app.listen(3000);
//前端全棧學習交流圈:866109386
//面向1-3經驗年前端開發人員
//幫助突破技術瓶頸,提升思維能力
中間件概念在編程中使用廣泛, 不管是前端還是後端, 在實際編程中或者框架設計都有使用到這種實用的模型。
基本上,Koa 所有的功能都是通過中間件實現的。
每個中間件默認接受兩個參數,第一個參數是 Context 對象,第二個參數是 next 函數。只要調用 next 函數,就可以把執行權轉交給下一個中間件。
如果中間件內部沒有調用 next 函數,那麼執行權就不會傳遞下去。
多箇中間件會形成一個棧結構(middle stack),以“先進後出”(first-in-last-out)的順序執行。整個過程就像,先是入棧,然後出棧的操作。
上面代碼的執行順序是:
請求 ==> x-response-time 中間件 ==> logger 中間件 ==> response中間件 ==> logger 中間件 ==> response-time 中間件 ==> 響應
理解 Koa 的中間件機制(源碼分析)
閱讀源碼,化繁為簡,我們看看 koa 的中間件系統是如何實現的。
function compose(middleware) {
return function(context, next) {
// last called middleware #
let index = -1;
return dispatch(0);
function dispatch(i) {
if (i <= index)
return Promise.reject(new Error("next() called multiple times"));
index = i;
let fn = middleware[i];
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve();
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err);
}
}
};
}
//前端全棧學習交流圈:866109386
//面向1-3經驗年前端開發人員
//幫助突破技術瓶頸,提升思維能力
我試圖去簡化一下這個方法,但方法本身已經足夠簡潔。
代碼很簡潔。
通過 next()傳遞 實現中間件調用, 結合 Promise 採用 遞歸調用 的通知機制。
看圖
這種形式的控制流讓整個 Koa 框架中間件的訪問呈現出 自上而下的中間件流 + 自下而上的 response 數據流 的形式。
Koa 本身做的工作僅僅是定製了中間件的編寫規範,而不內置任何中間件。一個 web request 會通過 Koa 的中間件棧,來動態完成 response 的處理。
koa 在中間件語法上面採用了 async + await 語法來生成 Promise 形式的程序控制流。
對前端的技術,架構技術感興趣的同學關注我的頭條號,並在後臺私信發送關鍵字:“前端”即可獲取免費的架構師學習資料
知識體系已整理好,歡迎免費領取。還有面試視頻分享可以免費獲取。關注我,可以獲得沒有的架構經驗哦!!
閱讀更多 前端全棧架構丶 的文章