Koa 中介軟體的執行
Node.js 中請求的處理討論 Koa 中介軟體前,先看原生 Node.js 中是如何建立 server 和處理請求的。 node_server.js const http = require("http"); const PORT = 3000; const server = http.createServer((req, res) => { res.end("hello world!"); }); server.listen(PORT); console.log(`server started at http://localhost:${PORT}`); Koa 中請求的處理Koa 也是通過上面的 koa/lib/application.js#L64 listen(...args) { debug('listen'); + const server = http.createServer(this.callback()); return server.listen(...args); } Koa 中的 hello world: server.js const Koa = require("koa"); const app = new Koa(); app.use(async ctx => { ctx.body = "Hello World"; }); app.listen(3000); Koa 中,涉及到對請求返回處理都是通過中介軟體完成的,像上面為樣,返回頁面一個 Koa 中介軟體編寫及使用Koa 中中介軟體即一個處理請求的方法,通過呼叫 koa/lib/application.js#L105 use(fn) { if (typeof fn !== 'function') throw new TypeError('middleware must be a function!'); if (isGeneratorFunction(fn)) { deprecate('Support for generators will be removed in v3. ' + 'See the documentation for examples of how to convert old middleware ' + 'https://github.com/koajs/koa/blob/master/docs/migration.md'); fn = convert(fn); } debug('use %s', fn._name || fn.name || '-'); this.middleware.push(fn); return this; } 通過上面的程式碼可看到,註冊的中介軟體被壓入 因為中介軟體中需要進行的操作是不可控的,完全有可能涉及非同步操作,比如從遠端獲取資料或從資料庫查詢資料後返回到 比如實現計算一個請求耗時的中介軟體,以下分別是通過普通函式配合 Promise 以及使用 來自官方 README 中使用 Promise 實現中介軟體的示例程式碼 // Middleware normally takes two parameters (ctx, next), ctx is the context for one request, // next is a function that is invoked to execute the downstream middleware. It returns a Promise with a then function for running code after completion. app.use((ctx, next) => { const start = Date.now(); return next().then(() => { const ms = Date.now() - start; console.log(`${ctx.method} ${ctx.url} - ${ms}ms`); }); }); 來自官方 README 中使用 app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; console.log(`${ctx.method} ${ctx.url} - ${ms}ms`); }); 可以看到,一箇中間件其簽名是 server.js app.use(async (ctx, next) => { console.log(1); next(); }); app.use(async (ctx, next) => { console.log(2); }); app.use(async (ctx, next) => { console.log(3); ctx.body = "Hello, world!"; }); 執行後控制檯輸出: $ node server.js 1 2 訪問頁面也不會看到
|