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