临时接到任务,要写中间件,然后就仿照了两篇博客,这两篇博客会在最后给出。
app.js
class App {
constructor() {
this.middlewares = [];
}
use(fn) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!');
this.middlewares.push(fn);
}
compose() {
const self = this;
return function (ctx, next) {
// last called middleware #
let index = -1
function dispatch(i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i
let fn = self.middlewares[i];
// 检测中间件有效性,为空时结束return Promise直接resolve
// 此时流程就会往回执行
if (i === self.middlewares.length) fn = next
if (!fn) return Promise.resolve()
// 中间件有效,resolve一个function回溯调用关键
try {
return Promise.resolve(fn(ctx, function next() {
// next()执行下一中间件
return dispatch(i + 1)
}))
} catch (err) {
return Promise.reject(err)
}
}
return dispatch(0)
}
}
// 创建全局上下文
createContext() {
const ctx = {
message: 'hello'
}
return ctx;
}
// 处理器
handles(ctx, fn) {
return fn(ctx);
}
callback() {
const fn = this.compose();
const ctx = this.createContext();
this.handles(ctx, fn);
}
}
module.exports = App;
使用demo测试
test.js
const App = require("./app2");
const app = new App();
// 异步函数
function fn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello');
}, 500);
});
}
function foo(a, b) {
return a * b
}
app.use(async (ctx, next) => {
ctx.a = '123';
console.log(foo(1, 1));
await next();
console.log(2);
});
app.use(async (ctx, next) => {
console.log(3,ctx.a,ctx.message);
console.log('fn', await fn())// 调用异步函数
await next();
console.log(4);
});
app.use(async (ctx, next) => {
console.log(5);
await next();
console.log(6);
});
app.callback();
参考链接: