what

inNode.jsMiddleware mainly refers to encapsulation of allHttpMethod of requesting details. At a timeHttpRequests usually involve a lot of work, such as logging,ipFiltering, query string, request body parsing,CookieProcessing, permission verification, parameter verification, exception handling, etc., but forWebIn terms of applications,I don’t want to deal with so many detailsTherefore, middleware is introduced to simplify and isolate the details between these infrastructures and business logic, so that developers can focus on business development to achieve the purpose of improving development efficiency. Its working model is shown in the following figure.

Middleware Implementation Method 1 (Express)

  • Three simple middleware are defined as follows:
const middleware1 = (req, res, next) => {
  console.log('middleware1 start')
  next()
}

const middleware2 = (req, res, next) => {
  console.log('middleware2 start')
  next()
}

const middleware3 = (req, res, next) => {
  console.log('middleware3 start')
  next()
}
Copy the code
  • In the form of recursion, the execution method of the subsequent middleware is passed to the current middleware, and at the end of the current middleware execution, through the callnext()Method to perform subsequent middleware calls.
// Middlewares const middlewares = [middleware1, middleware2, middleware3] function run (req, Res) {const next = () => {shift:get&delete const middleware = middlewares.shift() if (middleware) {middleware(req, res, next)}} next()} run() // Emulated a requestCopy the code

After executing the above code, you can see the following:

middleware1 start
middleware2 start
middleware3 start
Copy the code
  • If there are asynchronous operations in the middleware, need to be called after the process of asynchronous operation has finishednext()Method, or the middleware cannot execute sequentially. rewritemiddleware2Middleware:
const middleware2 = (req, res, next) => { console.log('middleware2 start') new Promise(resolve => { setTimeout(() => resolve(), Then (() => {next()})} // Middleware3 will execute after MIDDLEware2 asynchronously completesCopy the code

Middleware Implementation Method two (KOA)

  • Some middleware needs to be executed not only before the business process, but also after the business process, such as the logging middleware that counts the time. In case one,Can’t innext()For asynchronous operations, the rest of the current middleware code is executed as a callback. So you can takenext()methodsThe subsequent operationEncapsulate (the next middleware to be invoked) into onePromiseObject (after next(), it executes and returns a promise) and is available internally to middlewarenext.then()The form completes the callback after the business process has finished. rewriterun()The method is as follows:
function run (req, Res) {const next = () => {const middleware = middlewares. Shift () if (middleware) { Resolve (Middleware (req, res, next))}} next()}Copy the code
  • The invocation method of middleware should be rewritten as:
Const middleware1 = (req, res, next) => {console.log('middleware1 start') That is, next() gets a promise (which makes it possible to call then) // promise.resolve () : directly encapsulates the result returned by the middleware as a promise object, Return next().then(() => {console.log('middleware1 end')})}Copy the code

Thanks to the automatic asynchronous process control of async function, middleware can also be implemented in the following ways:

Const middleware2 = async (req, res, Next) => {console.log('middleware2 start') await new Promise(resolve => { SetTimeout (() => resolve(), 1000)}) await next() console.log('middleware2 end') Next.then ().catch() const middleware3 = async (req, res, next) => { console.log('middleware3 start') await next() console.log('middleware3 end') }Copy the code

Comparison of Middleware mechanisms for Express KOA

  • Advantages over Express: Express is not available innext()For asynchronous operations, the next code in the current middleware is executed as a callback