理解任务执行的洋葱模型 - koa

1. 什么是洋葱模型

洋葱模型,是 koa 中间件的执行顺序,洋葱模型的执行顺序是:

  • 中间件 A 开始执行
  • 中间件 A 执行完毕,执行下一个中间件 B
  • 中间件 B 执行完毕,执行下一个中间件 C
    ….

2. 实现一个洋葱模型的任务执行构造函数

需求:实现一个构造函数满足以下需求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const t = new TaskPro();
t.addTask(async (next) => {
console.log("1", "start");
await next();
console.log("1", "end");
});
t.addTask(() => {
console.log("2");
});
t.addTask(() => {
console.log("3");
});

t.run(); // 输出 1 start 2 3 1 end

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class TaskPro {
// 添加任务
_tasklist = [];
//当前任务正在执行标识
_running = false;
//要执行任务的下标
_currentIndex = 0;

//添加任务
addTask(task) {
this._tasklist.push(task);
}
async run() {
/**
* 边界情况判定,如果当前任务正在执行,直接return
* 否则,开始执行任务
*/

if (this._running) return;
// 未在执行任务,设置标识
this._running = true;
// 执行任务
this._runTask();
}

async _next() {
// 执行下一个任务
this._currentIndex++;
this._runTask();
}
async _runTask() {
// 边界情况判定
if (this._currentIndex >= this._tasklist.length) {
// 所有任务执行完毕,设置标识
this._running = false;
// 清空任务列表
this._tasklist = [];
return;
}
// 记录任务执行之前的下标
const prevIndex = this._currentIndex;

// 获取当前任务
const task = this._tasklist[this._currentIndex];

// 执行当前任务
await task(this._next.bind(this));
// 记录任务执行之后的下标
const nextIndex = this._currentIndex;
// 边界情况判定
if (prevIndex === nextIndex) {
// 当前任务执行完毕,执行下一个任务
this._next();
}
}
}


//-------- 结果 ----------
const t = new TaskPro();
t.addTask(async (next) => {
console.log("1", "start");
await next();
console.log("1", "end");
});
t.addTask(() => {
console.log("2");
});
t.addTask(() => {
console.log("3");
});
t.run(); // 输出 1 start 2 3 1 end

理解任务执行的洋葱模型 - koa
https://blog.funfe.cn/2024/03/19/20240319124707/
作者
李鹏杰
发布于
2024年3月19日
许可协议