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