@taicode/common-base 4.0.0-beta.1 → 4.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disposer.d.ts","sourceRoot":"","sources":["../../source/disposer/disposer.ts"],"names":[],"mappings":"AAEA,KAAK,eAAe,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAEvD,qBAAa,QAAQ;IACnB,OAAO,CAAC,gBAAgB,CAAwB;IAGhD,
|
|
1
|
+
{"version":3,"file":"disposer.d.ts","sourceRoot":"","sources":["../../source/disposer/disposer.ts"],"names":[],"mappings":"AAEA,KAAK,eAAe,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAEvD,qBAAa,QAAQ;IACnB,OAAO,CAAC,gBAAgB,CAAwB;IAGhD,GAAG,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IAK/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAa/B"}
|
|
@@ -2,14 +2,15 @@ import { logger } from '../logger/index.js';
|
|
|
2
2
|
export class Disposer {
|
|
3
3
|
cleanupFunctions = [];
|
|
4
4
|
// 添加清理函数
|
|
5
|
-
|
|
5
|
+
add(cleanupFn) {
|
|
6
6
|
this.cleanupFunctions.push(cleanupFn);
|
|
7
7
|
}
|
|
8
|
-
//
|
|
8
|
+
// 执行所有清理函数(LIFO:后注册的先执行)
|
|
9
9
|
async dispose() {
|
|
10
10
|
const cleanupFunctions = this.cleanupFunctions;
|
|
11
11
|
this.cleanupFunctions = [];
|
|
12
|
-
|
|
12
|
+
// 后创建的东西依赖先创建的,必须**后**销毁:逆注册序执行
|
|
13
|
+
for (const cleanupFn of [...cleanupFunctions].reverse()) {
|
|
13
14
|
try {
|
|
14
15
|
await cleanupFn();
|
|
15
16
|
}
|
|
@@ -6,20 +6,20 @@ describe('Disposer', () => {
|
|
|
6
6
|
beforeEach(() => {
|
|
7
7
|
disposer = new Disposer();
|
|
8
8
|
});
|
|
9
|
-
describe('
|
|
9
|
+
describe('add', () => {
|
|
10
10
|
it('应该能够添加清理函数', () => {
|
|
11
11
|
const cleanupFn = vi.fn();
|
|
12
12
|
expect(() => {
|
|
13
|
-
disposer.
|
|
13
|
+
disposer.add(cleanupFn);
|
|
14
14
|
}).not.toThrow();
|
|
15
15
|
});
|
|
16
16
|
it('应该能够添加多个清理函数', async () => {
|
|
17
17
|
const cleanupFn1 = vi.fn();
|
|
18
18
|
const cleanupFn2 = vi.fn();
|
|
19
19
|
const cleanupFn3 = vi.fn();
|
|
20
|
-
disposer.
|
|
21
|
-
disposer.
|
|
22
|
-
disposer.
|
|
20
|
+
disposer.add(cleanupFn1);
|
|
21
|
+
disposer.add(cleanupFn2);
|
|
22
|
+
disposer.add(cleanupFn3);
|
|
23
23
|
await disposer.dispose();
|
|
24
24
|
expect(cleanupFn1).toHaveBeenCalledOnce();
|
|
25
25
|
expect(cleanupFn2).toHaveBeenCalledOnce();
|
|
@@ -30,10 +30,10 @@ describe('Disposer', () => {
|
|
|
30
30
|
const stringFn = vi.fn(() => 'cleanup result');
|
|
31
31
|
const numberFn = vi.fn(() => 42);
|
|
32
32
|
const promiseFn = vi.fn(() => Promise.resolve('async cleanup'));
|
|
33
|
-
disposer.
|
|
34
|
-
disposer.
|
|
35
|
-
disposer.
|
|
36
|
-
disposer.
|
|
33
|
+
disposer.add(voidFn);
|
|
34
|
+
disposer.add(stringFn);
|
|
35
|
+
disposer.add(numberFn);
|
|
36
|
+
disposer.add(promiseFn);
|
|
37
37
|
await disposer.dispose();
|
|
38
38
|
expect(voidFn).toHaveBeenCalled();
|
|
39
39
|
expect(stringFn).toHaveBeenCalled();
|
|
@@ -46,38 +46,39 @@ describe('Disposer', () => {
|
|
|
46
46
|
const cleanupFn1 = vi.fn();
|
|
47
47
|
const cleanupFn2 = vi.fn();
|
|
48
48
|
const cleanupFn3 = vi.fn();
|
|
49
|
-
disposer.
|
|
50
|
-
disposer.
|
|
51
|
-
disposer.
|
|
49
|
+
disposer.add(cleanupFn1);
|
|
50
|
+
disposer.add(cleanupFn2);
|
|
51
|
+
disposer.add(cleanupFn3);
|
|
52
52
|
await disposer.dispose();
|
|
53
53
|
expect(cleanupFn1).toHaveBeenCalledOnce();
|
|
54
54
|
expect(cleanupFn2).toHaveBeenCalledOnce();
|
|
55
55
|
expect(cleanupFn3).toHaveBeenCalledOnce();
|
|
56
56
|
});
|
|
57
|
-
it('
|
|
57
|
+
it('应该按添加顺序的**逆序**(LIFO)执行清理函数', async () => {
|
|
58
58
|
const executionOrder = [];
|
|
59
|
-
disposer.
|
|
60
|
-
disposer.
|
|
61
|
-
disposer.
|
|
59
|
+
disposer.add(() => executionOrder.push(1));
|
|
60
|
+
disposer.add(() => executionOrder.push(2));
|
|
61
|
+
disposer.add(() => executionOrder.push(3));
|
|
62
62
|
await disposer.dispose();
|
|
63
|
-
|
|
63
|
+
// 后创建的东西依赖先创建的,必须后销毁
|
|
64
|
+
expect(executionOrder).toEqual([3, 2, 1]);
|
|
64
65
|
});
|
|
65
|
-
it('
|
|
66
|
+
it('应该按添加顺序的**逆序**(LIFO)执行异步清理函数', async () => {
|
|
66
67
|
const executionOrder = [];
|
|
67
|
-
disposer.
|
|
68
|
+
disposer.add(async () => {
|
|
68
69
|
await Promise.resolve();
|
|
69
70
|
executionOrder.push(1);
|
|
70
71
|
});
|
|
71
|
-
disposer.
|
|
72
|
+
disposer.add(async () => {
|
|
72
73
|
await Promise.resolve();
|
|
73
74
|
executionOrder.push(2);
|
|
74
75
|
});
|
|
75
|
-
disposer.
|
|
76
|
+
disposer.add(async () => {
|
|
76
77
|
await Promise.resolve();
|
|
77
78
|
executionOrder.push(3);
|
|
78
79
|
});
|
|
79
80
|
await disposer.dispose();
|
|
80
|
-
expect(executionOrder).toEqual([
|
|
81
|
+
expect(executionOrder).toEqual([3, 2, 1]);
|
|
81
82
|
});
|
|
82
83
|
it('应该处理清理函数中的错误', async () => {
|
|
83
84
|
const workingFn1 = vi.fn();
|
|
@@ -87,9 +88,9 @@ describe('Disposer', () => {
|
|
|
87
88
|
const workingFn2 = vi.fn();
|
|
88
89
|
// 模拟 logger.error
|
|
89
90
|
const loggerErrorSpy = vi.spyOn(logger, 'error').mockImplementation(() => { });
|
|
90
|
-
disposer.
|
|
91
|
-
disposer.
|
|
92
|
-
disposer.
|
|
91
|
+
disposer.add(workingFn1);
|
|
92
|
+
disposer.add(errorFn);
|
|
93
|
+
disposer.add(workingFn2);
|
|
93
94
|
// dispose 不应该抛出错误
|
|
94
95
|
await expect(disposer.dispose()).resolves.toBeUndefined();
|
|
95
96
|
// 所有函数都应该被调用
|
|
@@ -102,7 +103,7 @@ describe('Disposer', () => {
|
|
|
102
103
|
});
|
|
103
104
|
it('应该在执行后清空清理函数列表', async () => {
|
|
104
105
|
const cleanupFn = vi.fn();
|
|
105
|
-
disposer.
|
|
106
|
+
disposer.add(cleanupFn);
|
|
106
107
|
await disposer.dispose();
|
|
107
108
|
expect(cleanupFn).toHaveBeenCalledOnce();
|
|
108
109
|
// 再次调用 dispose 不应该执行任何函数
|
|
@@ -112,9 +113,9 @@ describe('Disposer', () => {
|
|
|
112
113
|
it('应该能够在清空后重新添加清理函数', async () => {
|
|
113
114
|
const firstCleanup = vi.fn();
|
|
114
115
|
const secondCleanup = vi.fn();
|
|
115
|
-
disposer.
|
|
116
|
+
disposer.add(firstCleanup);
|
|
116
117
|
await disposer.dispose();
|
|
117
|
-
disposer.
|
|
118
|
+
disposer.add(secondCleanup);
|
|
118
119
|
await disposer.dispose();
|
|
119
120
|
expect(firstCleanup).toHaveBeenCalledOnce();
|
|
120
121
|
expect(secondCleanup).toHaveBeenCalledOnce();
|
|
@@ -124,7 +125,7 @@ describe('Disposer', () => {
|
|
|
124
125
|
});
|
|
125
126
|
it('应该能够多次调用 dispose', async () => {
|
|
126
127
|
const cleanupFn = vi.fn();
|
|
127
|
-
disposer.
|
|
128
|
+
disposer.add(cleanupFn);
|
|
128
129
|
await disposer.dispose();
|
|
129
130
|
await disposer.dispose();
|
|
130
131
|
await disposer.dispose();
|
|
@@ -135,8 +136,8 @@ describe('Disposer', () => {
|
|
|
135
136
|
it('应该能够清理事件监听器', async () => {
|
|
136
137
|
const removeEventListener = vi.fn();
|
|
137
138
|
const unsubscribe = vi.fn();
|
|
138
|
-
disposer.
|
|
139
|
-
disposer.
|
|
139
|
+
disposer.add(removeEventListener);
|
|
140
|
+
disposer.add(unsubscribe);
|
|
140
141
|
await disposer.dispose();
|
|
141
142
|
expect(removeEventListener).toHaveBeenCalled();
|
|
142
143
|
expect(unsubscribe).toHaveBeenCalled();
|
|
@@ -144,8 +145,8 @@ describe('Disposer', () => {
|
|
|
144
145
|
it('应该能够清理定时器', async () => {
|
|
145
146
|
const clearTimeout = vi.fn();
|
|
146
147
|
const clearInterval = vi.fn();
|
|
147
|
-
disposer.
|
|
148
|
-
disposer.
|
|
148
|
+
disposer.add(() => clearTimeout(123));
|
|
149
|
+
disposer.add(() => clearInterval(456));
|
|
149
150
|
await disposer.dispose();
|
|
150
151
|
expect(clearTimeout).toHaveBeenCalledWith(123);
|
|
151
152
|
expect(clearInterval).toHaveBeenCalledWith(456);
|
|
@@ -153,8 +154,8 @@ describe('Disposer', () => {
|
|
|
153
154
|
it('应该能够清理资源连接', async () => {
|
|
154
155
|
const closeConnection = vi.fn();
|
|
155
156
|
const releaseResource = vi.fn();
|
|
156
|
-
disposer.
|
|
157
|
-
disposer.
|
|
157
|
+
disposer.add(() => closeConnection());
|
|
158
|
+
disposer.add(() => releaseResource());
|
|
158
159
|
await disposer.dispose();
|
|
159
160
|
expect(closeConnection).toHaveBeenCalled();
|
|
160
161
|
expect(releaseResource).toHaveBeenCalled();
|
|
@@ -167,9 +168,9 @@ describe('Disposer', () => {
|
|
|
167
168
|
};
|
|
168
169
|
const offFunction1 = mockEventEmitter.on('event1', vi.fn());
|
|
169
170
|
const offFunction2 = mockEventEmitter.on('event2', vi.fn());
|
|
170
|
-
disposer.
|
|
171
|
-
disposer.
|
|
172
|
-
disposer.
|
|
171
|
+
disposer.add(offFunction1);
|
|
172
|
+
disposer.add(offFunction2);
|
|
173
|
+
disposer.add(() => mockEventEmitter.cleanup());
|
|
173
174
|
await disposer.dispose();
|
|
174
175
|
expect(offFunction1).toHaveBeenCalled();
|
|
175
176
|
expect(offFunction2).toHaveBeenCalled();
|
|
@@ -180,7 +181,7 @@ describe('Disposer', () => {
|
|
|
180
181
|
it('应该捕获并记录同步错误', async () => {
|
|
181
182
|
const loggerErrorSpy = vi.spyOn(logger, 'error').mockImplementation(() => { });
|
|
182
183
|
const error = new Error('Sync error');
|
|
183
|
-
disposer.
|
|
184
|
+
disposer.add(() => {
|
|
184
185
|
throw error;
|
|
185
186
|
});
|
|
186
187
|
await disposer.dispose();
|
|
@@ -189,13 +190,13 @@ describe('Disposer', () => {
|
|
|
189
190
|
});
|
|
190
191
|
it('应该处理不同类型的错误', async () => {
|
|
191
192
|
const loggerErrorSpy = vi.spyOn(logger, 'error').mockImplementation(() => { });
|
|
192
|
-
disposer.
|
|
193
|
+
disposer.add(() => {
|
|
193
194
|
throw new TypeError('Type error');
|
|
194
195
|
});
|
|
195
|
-
disposer.
|
|
196
|
+
disposer.add(() => {
|
|
196
197
|
throw 'String error';
|
|
197
198
|
});
|
|
198
|
-
disposer.
|
|
199
|
+
disposer.add(() => {
|
|
199
200
|
throw { message: 'Object error' };
|
|
200
201
|
});
|
|
201
202
|
await disposer.dispose();
|
|
@@ -205,7 +206,7 @@ describe('Disposer', () => {
|
|
|
205
206
|
it('应该捕获并记录异步错误', async () => {
|
|
206
207
|
const loggerErrorSpy = vi.spyOn(logger, 'error').mockImplementation(() => { });
|
|
207
208
|
const asyncError = new Error('Async error');
|
|
208
|
-
disposer.
|
|
209
|
+
disposer.add(async () => {
|
|
209
210
|
throw asyncError;
|
|
210
211
|
});
|
|
211
212
|
await disposer.dispose();
|