let http = require('http')
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'})
response.end('Hello World')
}).listen(8081, () = > {console.log('Server running at http://127.0.0.1:8081/)})Copy the code
This is how the HTTP core module of Node is used. Koa solves three problems of the HTTP module
Problems with native HTTP modules
- A flaw in the way the code is written, where all the logic is coupled in one function
- Req and RES are weak
- HTTP cannot uniformly handle errors based on callbacks
Koa’s answer
The middleware
-
By constructing middleware to slice logic, async function is used to make asynchronous code have synchronous writing mode
-
Koa middleware has a classic Onion model
Requests pass through the outer middleware to the inner middleware and back to the outer, similar to DOM event capture and bubbling.
Each layer is an async function so each layer has the ability to wait for the lower layer middleware to finish before continuing, of course you need to make sure you write await before next(), otherwise the layer will continue without waiting for the lower layer.
Since each layer is a function, it is easy to build the Onion model, with functions within functions, passing the lower middleware to the upper middleware, which calls it.
use(callback) { // Register middleware
this.middlewares.push(callback)
}
compose(ctx) { // Build the onion model
// Link multiple promises together to form a promise chain
const dispatch = i= > {
if (i === this.middlewares.length) return Promise.resolve()
let middleware = this.middlewares[i]
// Pass the lower level middleware to the upper level middleware via deferred call functions
return Promise.resolve(middleware(ctx, () => dispatch(i+1)))}return dispatch(0)}Copy the code
Extend REQ and RES
Koa instances rely on request, Response, and Context extension objects, and each Koa instance maintains a separate extension object
Request is an extension to REq, Response is an extension to RES, and the context object proxies some functions of Request and Response
Each request also maintains a separate extension object
createContext(req, res) { // Build CTX by extending reQ and RES functionality
// Ensure that no context is shared on each request
let ctx = Object.create(this.context)
let _request = Object.create(this.request)
let _response = Object.create(this.response)
ctx.request = _request
ctx.req = ctx.request.req = req
ctx.response = _response
ctx.res = ctx.response.res = res
return ctx
}
Copy the code
What does it extend, for example, ctx.url
/*context*/
module.exports = {
get url() {
return this.request.url
}
}
Copy the code
/*request*/
module.exports = {
get url() {
return this.req.url
}
}
Copy the code
Request acts as a layer 1 proxy to extend REQ, and context acts as a layer 2 proxy to get extensions on Request and Response
Unified handling of errors based on the event module
Koa inherits the Emitter (Events) module in Node, which has the function of publishing and subscribling.it can publish error events and monitor them