@leafer/task 1.0.0-beta.12 → 1.0.0-beta.15
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.
- package/package.json +7 -5
- package/types/index.d.ts +54 -0
- package/src/TaskItem.ts +0 -47
- package/src/TaskProcessor.ts +0 -282
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer/task",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"description": "@leafer/task",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "src/index.ts",
|
|
8
|
+
"types": "types/index.d.ts",
|
|
8
9
|
"files": [
|
|
9
|
-
"
|
|
10
|
+
"types",
|
|
11
|
+
"dist"
|
|
10
12
|
],
|
|
11
13
|
"repository": {
|
|
12
14
|
"type": "git",
|
|
@@ -19,10 +21,10 @@
|
|
|
19
21
|
"leaferjs"
|
|
20
22
|
],
|
|
21
23
|
"dependencies": {
|
|
22
|
-
"@leafer/math": "1.0.0-beta.
|
|
23
|
-
"@leafer/debug": "1.0.0-beta.
|
|
24
|
+
"@leafer/math": "1.0.0-beta.15",
|
|
25
|
+
"@leafer/debug": "1.0.0-beta.15"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"@leafer/interface": "1.0.0-beta.
|
|
28
|
+
"@leafer/interface": "1.0.0-beta.15"
|
|
27
29
|
}
|
|
28
30
|
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ITaskProcessor, ITaskProcessorConfig, ITaskItem, IFunction, ITaskOptions } from '@leafer/interface';
|
|
2
|
+
|
|
3
|
+
declare class TaskProcessor implements ITaskProcessor {
|
|
4
|
+
config: ITaskProcessorConfig;
|
|
5
|
+
protected list: ITaskItem[];
|
|
6
|
+
protected parallelList: ITaskItem[];
|
|
7
|
+
protected parallelSuccessNumber: number;
|
|
8
|
+
running: boolean;
|
|
9
|
+
isComplete: boolean;
|
|
10
|
+
protected timer: any;
|
|
11
|
+
get total(): number;
|
|
12
|
+
index: number;
|
|
13
|
+
delayNumber: number;
|
|
14
|
+
get finishedIndex(): number;
|
|
15
|
+
get remain(): number;
|
|
16
|
+
get percent(): number;
|
|
17
|
+
constructor(config?: ITaskProcessorConfig);
|
|
18
|
+
add(taskCallback: IFunction, options?: ITaskOptions | number): ITaskItem;
|
|
19
|
+
protected push(task: ITaskItem, start?: boolean): void;
|
|
20
|
+
protected empty(): void;
|
|
21
|
+
start(): void;
|
|
22
|
+
pause(): void;
|
|
23
|
+
resume(): void;
|
|
24
|
+
skip(): void;
|
|
25
|
+
stop(): void;
|
|
26
|
+
protected run(): void;
|
|
27
|
+
protected runTask(): void;
|
|
28
|
+
protected runParallelTasks(): void;
|
|
29
|
+
protected runParallelTask(task: ITaskItem): void;
|
|
30
|
+
private nextTask;
|
|
31
|
+
protected setParallelList(): void;
|
|
32
|
+
protected fillParallelTask(): void;
|
|
33
|
+
protected onComplete(): void;
|
|
34
|
+
protected onTask(task: ITaskItem): void;
|
|
35
|
+
protected onParallelError(error: unknown): void;
|
|
36
|
+
protected onError(error: unknown): void;
|
|
37
|
+
destroy(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare class TaskItem implements ITaskItem {
|
|
41
|
+
readonly id: number;
|
|
42
|
+
parent: TaskProcessor;
|
|
43
|
+
parallel: boolean;
|
|
44
|
+
time: number;
|
|
45
|
+
isComplete: boolean;
|
|
46
|
+
isCancel: boolean;
|
|
47
|
+
private task;
|
|
48
|
+
constructor(task?: IFunction);
|
|
49
|
+
run(): Promise<void>;
|
|
50
|
+
complete(): void;
|
|
51
|
+
cancel(): void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { TaskItem, TaskProcessor };
|
package/src/TaskItem.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { IFunction, ITaskItem } from '@leafer/interface'
|
|
2
|
-
import { IncrementId } from '@leafer/math'
|
|
3
|
-
import { Debug } from '@leafer/debug'
|
|
4
|
-
|
|
5
|
-
import { TaskProcessor } from './TaskProcessor'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const debug = Debug.get('TaskProcessor')
|
|
9
|
-
export class TaskItem implements ITaskItem {
|
|
10
|
-
|
|
11
|
-
readonly id: number
|
|
12
|
-
|
|
13
|
-
public parent: TaskProcessor
|
|
14
|
-
|
|
15
|
-
public parallel = true
|
|
16
|
-
public time = 1 // 预估任务需要运行的时间, 毫秒为单位
|
|
17
|
-
|
|
18
|
-
public isComplete: boolean
|
|
19
|
-
public isCancel: boolean
|
|
20
|
-
|
|
21
|
-
private task: IFunction
|
|
22
|
-
|
|
23
|
-
constructor(task?: IFunction) {
|
|
24
|
-
this.id = IncrementId.create(IncrementId.TASK)
|
|
25
|
-
this.task = task
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async run(): Promise<void> {
|
|
29
|
-
try {
|
|
30
|
-
if (this.task && !this.isComplete && this.parent.running) await this.task()
|
|
31
|
-
} catch (error) {
|
|
32
|
-
debug.error(error)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public complete(): void {
|
|
37
|
-
this.isComplete = true
|
|
38
|
-
this.parent = null
|
|
39
|
-
this.task = null
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public cancel(): void {
|
|
43
|
-
this.isCancel = true
|
|
44
|
-
this.complete()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
}
|
package/src/TaskProcessor.ts
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import { IFunction, ITaskProcessor, ITaskProcessorConfig, ITaskOptions, ITaskItem } from '@leafer/interface'
|
|
2
|
-
import { DataHelper } from '@leafer/data'
|
|
3
|
-
|
|
4
|
-
import { TaskItem } from './TaskItem'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export class TaskProcessor implements ITaskProcessor {
|
|
8
|
-
|
|
9
|
-
public config: ITaskProcessorConfig = { parallel: 6 }
|
|
10
|
-
|
|
11
|
-
protected list: ITaskItem[] = []
|
|
12
|
-
|
|
13
|
-
protected parallelList: ITaskItem[]
|
|
14
|
-
protected parallelSuccessNumber: number
|
|
15
|
-
|
|
16
|
-
public running = false
|
|
17
|
-
public isComplete = true
|
|
18
|
-
|
|
19
|
-
protected timer: any
|
|
20
|
-
|
|
21
|
-
public get total(): number {
|
|
22
|
-
return this.list.length + this.delayNumber
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public index = 0
|
|
26
|
-
|
|
27
|
-
public delayNumber = 0
|
|
28
|
-
|
|
29
|
-
public get finishedIndex(): number {
|
|
30
|
-
return this.isComplete ? 0 : this.index + this.parallelSuccessNumber
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
public get remain(): number {
|
|
34
|
-
return this.isComplete ? this.total : this.total - this.finishedIndex
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public get percent(): number {
|
|
38
|
-
const { total } = this
|
|
39
|
-
let totalTime = 0, runTime = 0
|
|
40
|
-
|
|
41
|
-
for (let i = 0; i < total; i++) {
|
|
42
|
-
if (i <= this.finishedIndex) {
|
|
43
|
-
runTime += this.list[i].time
|
|
44
|
-
if (i === this.finishedIndex) totalTime = runTime
|
|
45
|
-
} else {
|
|
46
|
-
totalTime += this.list[i].time
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return this.isComplete ? 1 : (runTime / totalTime)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
constructor(config?: ITaskProcessorConfig) {
|
|
55
|
-
if (config) DataHelper.assign(this.config, config)
|
|
56
|
-
this.empty()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// list
|
|
60
|
-
|
|
61
|
-
public add(taskCallback: IFunction, options?: ITaskOptions | number): ITaskItem {
|
|
62
|
-
let start: boolean, parallel: boolean, time: number, delay: number
|
|
63
|
-
|
|
64
|
-
const task = new TaskItem(taskCallback)
|
|
65
|
-
task.parent = this
|
|
66
|
-
|
|
67
|
-
if (typeof options === 'number') {
|
|
68
|
-
delay = options
|
|
69
|
-
} else if (options) {
|
|
70
|
-
parallel = options.parallel
|
|
71
|
-
start = options.start
|
|
72
|
-
time = options.time
|
|
73
|
-
delay = options.delay
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (time) task.time = time
|
|
77
|
-
if (parallel === false) task.parallel = false
|
|
78
|
-
|
|
79
|
-
if (delay === undefined) {
|
|
80
|
-
this.push(task, start)
|
|
81
|
-
} else {
|
|
82
|
-
this.delayNumber++
|
|
83
|
-
setTimeout(() => {
|
|
84
|
-
this.delayNumber--
|
|
85
|
-
this.push(task, start)
|
|
86
|
-
}, delay)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this.isComplete = false
|
|
90
|
-
|
|
91
|
-
return task
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
protected push(task: ITaskItem, start?: boolean): void {
|
|
95
|
-
this.list.push(task)
|
|
96
|
-
if (start !== false && !this.timer) {
|
|
97
|
-
this.timer = setTimeout(() => this.start())
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
protected empty(): void {
|
|
102
|
-
this.index = 0
|
|
103
|
-
this.parallelSuccessNumber = 0
|
|
104
|
-
this.list = []
|
|
105
|
-
this.parallelList = []
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// control
|
|
109
|
-
|
|
110
|
-
public start(): void {
|
|
111
|
-
if (!this.running) {
|
|
112
|
-
this.running = true
|
|
113
|
-
this.isComplete = false
|
|
114
|
-
this.run()
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
public pause(): void {
|
|
119
|
-
clearTimeout(this.timer)
|
|
120
|
-
this.timer = null
|
|
121
|
-
this.running = false
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
public resume(): void {
|
|
125
|
-
this.start()
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
public skip(): void {
|
|
129
|
-
this.index++
|
|
130
|
-
this.resume()
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
public stop(): void {
|
|
134
|
-
this.isComplete = true
|
|
135
|
-
this.list.forEach(task => { if (!task.isComplete) task.cancel() })
|
|
136
|
-
this.pause()
|
|
137
|
-
this.empty()
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// run
|
|
141
|
-
|
|
142
|
-
protected run(): void {
|
|
143
|
-
if (!this.running) return
|
|
144
|
-
|
|
145
|
-
this.setParallelList()
|
|
146
|
-
|
|
147
|
-
if (this.parallelList.length > 1) {
|
|
148
|
-
|
|
149
|
-
this.runParallelTasks()
|
|
150
|
-
|
|
151
|
-
} else {
|
|
152
|
-
|
|
153
|
-
this.remain ? this.runTask() : this.onComplete()
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
protected runTask(): void {
|
|
159
|
-
const task = this.list[this.index]
|
|
160
|
-
task.run().then(() => {
|
|
161
|
-
|
|
162
|
-
this.onTask(task)
|
|
163
|
-
|
|
164
|
-
this.index++
|
|
165
|
-
this.nextTask()
|
|
166
|
-
|
|
167
|
-
}).catch(error => {
|
|
168
|
-
this.onError(error)
|
|
169
|
-
})
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
protected runParallelTasks(): void {
|
|
173
|
-
this.parallelList.forEach(task => this.runParallelTask(task))
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
protected runParallelTask(task: ITaskItem): void {
|
|
177
|
-
task.run().then(() => {
|
|
178
|
-
|
|
179
|
-
this.onTask(task)
|
|
180
|
-
this.fillParallelTask()
|
|
181
|
-
|
|
182
|
-
}).catch(error => {
|
|
183
|
-
this.onParallelError(error)
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private nextTask(): void {
|
|
188
|
-
if (this.total === this.finishedIndex) {
|
|
189
|
-
this.onComplete()
|
|
190
|
-
} else {
|
|
191
|
-
this.timer = setTimeout(() => this.run())
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
protected setParallelList(): void {
|
|
196
|
-
let task: ITaskItem
|
|
197
|
-
|
|
198
|
-
this.parallelList = []
|
|
199
|
-
this.parallelSuccessNumber = 0
|
|
200
|
-
let end = this.index + this.config.parallel
|
|
201
|
-
|
|
202
|
-
if (end > this.list.length) end = this.list.length
|
|
203
|
-
|
|
204
|
-
for (let i = this.index; i < end; i++) {
|
|
205
|
-
task = this.list[i]
|
|
206
|
-
if (task.parallel) {
|
|
207
|
-
this.parallelList.push(task)
|
|
208
|
-
} else {
|
|
209
|
-
break
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
protected fillParallelTask(): void {
|
|
216
|
-
let task: ITaskItem
|
|
217
|
-
const parallelList = this.parallelList
|
|
218
|
-
|
|
219
|
-
// 完成一个任务
|
|
220
|
-
this.parallelSuccessNumber++
|
|
221
|
-
parallelList.pop()
|
|
222
|
-
|
|
223
|
-
// 找到下一个可以并行的任务
|
|
224
|
-
const parallelWaitNumber = parallelList.length
|
|
225
|
-
const nextIndex = this.finishedIndex + parallelWaitNumber
|
|
226
|
-
|
|
227
|
-
if (parallelList.length) {
|
|
228
|
-
|
|
229
|
-
if (!this.running) return
|
|
230
|
-
|
|
231
|
-
if (nextIndex < this.total) {
|
|
232
|
-
|
|
233
|
-
task = this.list[nextIndex]
|
|
234
|
-
|
|
235
|
-
if (task.parallel) {
|
|
236
|
-
parallelList.push(task)
|
|
237
|
-
this.runParallelTask(task)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
} else {
|
|
243
|
-
|
|
244
|
-
this.index += this.parallelSuccessNumber
|
|
245
|
-
this.parallelSuccessNumber = 0
|
|
246
|
-
this.nextTask()
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// event
|
|
252
|
-
|
|
253
|
-
protected onComplete(): void {
|
|
254
|
-
this.stop()
|
|
255
|
-
if (this.config.onComplete) this.config.onComplete()
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
protected onTask(task: ITaskItem): void {
|
|
259
|
-
task.complete()
|
|
260
|
-
if (this.config.onTask) this.config.onTask()
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
protected onParallelError(error: unknown): void {
|
|
264
|
-
// 并行变串行, 以便下次重试
|
|
265
|
-
this.parallelList.forEach(task => {
|
|
266
|
-
task.parallel = false
|
|
267
|
-
})
|
|
268
|
-
this.parallelList.length = 0
|
|
269
|
-
this.parallelSuccessNumber = 0
|
|
270
|
-
|
|
271
|
-
this.onError(error)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
protected onError(error: unknown): void {
|
|
275
|
-
this.pause()
|
|
276
|
-
if (this.config.onError) this.config.onError(error)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
public destroy(): void {
|
|
280
|
-
this.stop()
|
|
281
|
-
}
|
|
282
|
-
}
|