+-
这是洋葱模型递归版,如何用循环方式实现?

迭代版洋葱模型的实现

// 函数集(相当于中间件集合) let arr = [ (next) => { console.log('a1'); next(); console.log('a2'); }, (next) => { console.log('b1'); next(); console.log('b2'); }, (next) => { console.log('c1'); next(); console.log('c2'); }, ]; // 用递归实现洋葱模型 let dispatch = (i) => { let fn = arr[i]; if (typeof fn !== 'function') return let next = () => dispatch(i + 1); fn(next) } dispatch(0) // 运行结果 ==> a1 > b1 > c1 > c2 > b2 > a1 // 那用循环怎么实现上面的结果?

有种说法是所有的递归都可以用非递归的方式实现

那以上的递归版的洋葱可以用循环来替代吗?

参考: 洋葱模型的实现

当然可以,我们可以手动模拟javascript调用栈的运行,不过为了简化对代码流的控制我们把next前后的代码分成before和after

type Command = { type: "GO" | "EXECUTE"; index: number; callback: (next: () => void) => void | null; }; type Middleware = { before: (next: () => void) => void; after: () => void; }; class App { private middlewares: Middleware[] = []; private commands: Command[] = []; use(middleware: Middleware) { this.middlewares.push(middleware); } run() { const { commands, middlewares } = this; commands.push({ type: "GO", index: 0, callback: null }); while (commands.length) { const { type, index, callback } = commands.pop(); /** * 不存在该任务,直接返回 */ if (index >= middlewares.length) { return; } switch (type) { case "GO": { commands.push({ type: "EXECUTE", index: index, callback: middlewares[index].before }); break; } case "EXECUTE": { callback(() => { commands.push({ type: "EXECUTE", index: index, callback: middlewares[index].after }); if (index + 1 < middlewares.length) { commands.push({ type: "GO", index: index + 1, callback: null }); } }); } } } } } const app = new App(); app.use({ before(next) { console.log("a1"); next(); }, after() { console.log("a2"); } }); app.use({ before(next) { console.log("b1"); next(); }, after() { console.log("b2"); } }); app.use({ before(next) { console.log("c1"); next(); }, after() { console.log("c2"); } }); app.run();