A, start
Let’s start with the following code:
const Koa = require("koa");
const app = new Koa();
app.use( (ctx, next) = > {
console.log(1);
next();
console.log(2);
});
app.use( (ctx, next) = > {
console.log(3);
next();
console.log(4);
});
app.use( (ctx, next) = > {
console.log(5);
next();
console.log(6);
});
app.listen(3000);
Copy the code
In normal logic, the output is: 1,2,3,4,5,6; But according to koa, the execution logic output is: 1,3,5,6,4,2; This output logic is called the Onion model (personal summary), and we will implement this output logic.
Second, the implementation
- Define middlewares, an array to store functions, and use, a function to store functions into arrays
Middlewares: [], const app = {middlewares: [],// Use: function (fn) {this.middlewares.push(fn); }}Copy the code
- Execute the use function and start storing the arguments (functions) from use into the array Middlewares
app.use((next) => {
console.log(1);
next();
console.log(2);
});
app.use((next) => {
console.log(3);
next();
console.log(4);
});
app.use((next) => {
console.log(5);
next();
console.log(6);
});
Copy the code
- Recursively executes the functions in the array
// Define the compose function to recursively execute the middlwares function. You can also define other function names, such as compose in KOA. Compose app.pose = function () {// Instead of returning a function, In order to emulate koA's logic return function () {// Define dispatch to execute function dispatch(idx) {// If (idx === app.middlewares. Length) {return; if (idx === app.middlewares. } // From middlewares const fn = app.middlewares[idx]; // Next fn(function next() {// Next will execute the next app.use argument passed in at dispatch(1), Start recursive dispatch(++ IDx); }); } // Pass in 0 to begin execution of the first function in middlewares, which executes the first function passed in app.use, dispatch(0); }; }; app.compose()();Copy the code
Third, summary
- The next function is the function passed in the next app.use;
- The third app.use next function returns idx = app.middlewares. Length;
- So console.log(6) is executed next; Console. log(4) is executed after the next function in the second app.use has been executed.
- When console.log(4) is finished, next in the first app.use function is finished.
- Log (2) is executed, and all code is executed