function A(next) {
console.log("A start");
typeof next === "function" && next();
console.log("A end");
}
function B(next) {
console.log("B start");
typeof next === "function" && next();
console.log("B end");
}
function C(next) {
console.log("C start");
typeof next === "function" && next();
console.log("C end");
}
function D() {
console.log("D start");
console.log("D end");
}
A(B.bind(null, C.bind(null, D)));
A start
B start
C start
D start
D end
C end
B end
A end
方式1:Array.prototype.reduceRight
const mws = [A, B, C, D];
function compose(allMW) {
return allMW.reduceRight((pre, cur) => {
return cur.bind(null, pre);
});
}
let mwFn = compose(mws);
mwFn();
const mws = [A, B, C, D];
function compose(allMW) {
function dispatch(i) {
let middleware = allMW[i];
if (!middleware) return;
return middleware.bind(null, dispatch(i + 1));
}
return dispatch(0);
}
let mwFn = compose(mws);
mwFn();
class Koa {
constructor() {
this.middlewareList = [];
this.context = {
request: null,
response: null,
};
}
use(middleware) {
this.middlewareList.push(middleware);
}
compose(middlewareList) {
return function (ctx) {
function dispatch(index) {
const middleware = middlewareList[index];
if (!middleware) return;
return middleware(ctx, dispatch.bind(null, index + 1));
}
return dispatch(0);
};
}
}
const app = new Koa();
app.use((ctx, next) => {
console.log("A start");
next();
console.log("A end");
});
app.use((ctx, next) => {
console.log("B start");
next();
console.log("B end");
});
app.use((ctx, next) => {
console.log("C start");
next();
console.log("C end");
});
app.use((ctx, next) => {
console.log("D start");
next();
console.log("D end");
});
const run = app.compose(app.middlewareList);
run();
A start
B start
C start
D start
D end
C end
B end
A end