Express and KOA are both Web frameworks created by the same team, and are being versioned to align with es6 standards. So let’s talk about what happened to the same team that wanted to make another KOA

express

When Express came out, JS was still in chaos and es6 standards were not out. The node event processing method is based on the FORM of CB (callback), which is a better way at that time. So the way the middleware in Express handles it is basically callback. With the advent of ES6, there are many new standards. This forced Express to consider compatibility with es6 syntaxes, which handle asynchronses with promises and then async and await syntaxes. (Express doesn’t mean you can’t use these syntactic sugar, it can be solved by using a third party library, just not as elegant as KOA)

The difference between

The difference here is from koA’s point of view, versus Express

A lightweight

Koa simplifies the framework based on Express and is less heavy than Express, mainly in the following two aspects:

  • Koa does not provide built-in middleware;
  • Koa does not provide routes, but separates the library of routes (KOA/Router).

In fact, from the analysis of both official websites, you can see that koA’s official website is a single page, while Express is a framework containing various middleware.

The structure is different

The object structure of Express looks like this.

app.get('/'.function (req, res) {
  	res.send('Hello World! ')})Copy the code

It is represented by a graph as follows:

In the case of KOA, it has an extra context layer than Express, which makes more sense to save some public parameters. The diagram below:

Koa more friendly support middleware

Why more friendly? Koa supports asynchronous middleware writing. With Express, the functionality is fine, but the code is not as readable

Suppose we have A situation where we need A-> B -> C -> B -> A to execute synchronous code in the order of middleware execution koA is no different from Express. The logic is as follows:

Express synchronization

app.use(function (req, res, next) {
  console.log(1);
  next();
  console.log(4);
  next();
})

// Middleware 2
app.use(function (req, res, next) {
  console.log(3);
  next();
})
Copy the code

The results of

Koa synchronization

app.use(function (ctx, next) {
  console.log(1);
  next();
  console.log(4);
});

// Middleware 2
app.use(function (ctx, next) {
  console.log(3);
  next();
})
Copy the code

The results of

There is little difference between the two codes for synchronous processing. You can do that, but often when you’re writing code, it’s not really all about synchronization.

Asynchronous processing

If we had this logic, it would look like this:

We want the order of output to be 1 -> 2 -> 3 -> 4

Processing in Express

// Simulate asynchrony
function delay(duration) {
  return new Promise(resolve= > {
    setTimeout(() = > {
      resolve();
    }, duration)
  })
}
// Middleware 1
app.use(async function (req, res, next) {
  console.log(1);
  next();
  // I originally need to put this logic in the second middleware, but the function can not be implemented in the second middleware
  await delay(1000);
  console.log(3);
  
  
  console.log(4);
  next();
})

// Middleware 2
app.use(asyncHandler(async function (req, res, next) {
  console.log(2);
}))
Copy the code

Although it is said here that the printed result is realized, it is not the same logic as in our diagram, which is not correct. If I write it in the same logic as the diagram.

// Simulate asynchrony
function delay(duration) {
  return new Promise(resolve= > {
    setTimeout(() = > {
      resolve();
    }, duration)
  })
}
// Middleware 1
app.use(async function (req, res, next) {
  console.log(1);
 await next();
  console.log(4);
  next();
})

// Middleware 2
app.use(asyncHandler(async function (req, res, next) {
  console.log(2);
  await delay(1000);
  console.log(3);
}))
Copy the code

The code requires this logic, but the result is different, as follows:

The original was when Express came out. There were no new standards like Promise and async await. Express could do things, just do them in a different way.

Koa implementation

// An example of KOA's middleware
function delay(duration) {
  return new Promise(resolve= > {
    setTimeout(() = > {
      resolve();
    }, duration)
  })
}
// Middleware 1
app.use(async function (ctx, next) {
  console.log(1);
  await next();
  console.log(4);
})

// Middleware 2
app.use(async function (ctx, next) {
  console.log(2);
  await delay(1000);
  console.log(3);
})
Copy the code

It can be seen that for each middleware, after completing something, it can elegantly transfer control to the next middleware and wait for it to complete. When the subsequent middleware finishes processing, control comes back to itself. This middleware model is called the Onion model