@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 CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "@leafer/task",
3
- "version": "1.0.0-beta.12",
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.12",
23
- "@leafer/debug": "1.0.0-beta.12"
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.12"
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,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
- }