TimeoutManager.ets
5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/**
* 超时控制与管理
*
* setTimeout和setInterval函数,都返回一个整数值,表示计数器编号。
*
* let timerId = setTimeout(func|code, delay);
* setTimeout函数接受两个参数,第一个参数func|code是将要推迟执行的函数名或者一段代码,第二个参数delay是推迟执行的毫秒数。
* setTimeout的第二个参数如果省略,则默认为0。
*
* 如:
* let timerId1 = setTimeout(fun1, 1000);
*
* setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。
* let intervalId1 = setInterval(fun2, 1000);
* 上面代码中,每隔1000毫秒就会执行fun2函数,会无限运行下去,直到关闭当前窗口。
*
* 注意:
* setInterval指定的是“开始执行”之间的间隔,并不考虑每次任务执行本身所消耗的时间。因此实际上,两次执行之间的间隔会小于指定的时间。
* 比如,setInterval指定每 100ms 执行一次,每次执行需要 5ms,那么第一次执行结束后95毫秒,第二次执行就会开始。如果某次执行耗时特别长,比如需要105毫秒,那么它结束后,下一次执行就会立即开始。
*
*
* setTimeout和setInterval函数,都返回一个整数值,表示计数器编号。将该整数传入clearTimeout和clearInterval函数,就可以取消对应的定时器。
*
* clearTimeout(timerId1)
* clearInterval(intervalId1)
*/
import { WDGroup } from '../layout/WDGroup';
import HashMap from '@ohos.util.HashMap';
import { Lego } from './LegoService';
export namespace Timeout {
/**
* 超时管理
*/
export class TimeoutManager {
/**
* 超时时长
*/
private static TASK_TIMEOUT: number = 5000;
/**
* 任务超时回调
*/
private callback: Callback;
/**
* 用于存放所有进行中的任务
*/
private taskMap: HashMap<WDGroup, Task>;
/**
* 超时管理器单例实例
*/
private static instance: TimeoutManager;
private intervalId:number = -1;
/**
* 构造函数
*
* @param group 发出请求的MGGroup实例
* @param startTime 任务开始时间戳
* @param timeout 超时限制时常
*/
constructor(callback: Callback) {
this.taskMap = new HashMap<WDGroup, Task>();
this.callback = callback;
// todo:
// 如果队列中没有检查消息,TASK_TIMEOUT后检查。
// if (this.intervalId == -1) {
// this.intervalId = setInterval(() => {
// this.checkTimeout();
// }, TimeoutManager.TASK_TIMEOUT);
// }
}
/**
* 添加任务,监控超时状态。
* @param group MGGroup对象
* @param callback 回调
*/
public addTask(group: WDGroup, callback: Lego.Callback) {
let task: Task = this.taskMap.get(group);
let timestamp: number = new Date().getTime(); // 单位毫秒
if (task == null) {
this.taskMap.set(group, new Task(group, callback, timestamp, TimeoutManager.TASK_TIMEOUT));
} else {
task.setStartTime(timestamp);
task.setCallback(callback);
}
}
/**
* 移除任务,说明任务已经完成,不再监控超时状态。
* @param group MGGroup对象
*/
public removeTask(group: WDGroup) {
this.taskMap.remove(group);
}
/**
* 检查是否有已经超时的任务,如有则回调超时状态。
*/
private checkTimeout() {
// TODO: 遍历任务列表检查是否有超时任务
this.taskMap.forEach((task: Task, group: WDGroup) => {
if (task == null || task.isTimeout()) {
// 超时回调
if (this.callback) {
this.callback.onTimeout(group, task.callback);
}
}
})
}
}
/**
* 任务
*/
class Task {
/**
* MGGroup实例
*/
private group: WDGroup;
/**
* 请求回调
*/
public callback: Lego.Callback;
/**
* 任务开始时间戳
*/
private startTime: number;
/**
* 超时限制时常
*/
private timeout: number;
/**
* 构造函数
*
* @param group 发出请求的MGGroup实例
* @param startTime 任务开始时间戳
* @param timeout 超时限制时常
*/
constructor(group: WDGroup, callback: Lego.Callback, startTime: number, timeout: number) {
this.group = group;
this.callback = callback;
this.startTime = startTime;
this.timeout = timeout;
}
/**
* 更新任务开始时间戳
*
* @param startTime 任务开始时间戳
*/
public setStartTime(startTime: number): void {
this.startTime = startTime;
}
public setCallback(callback: Lego.Callback): void {
this.callback = callback;
}
/**
* 检查任务是否超时
*
* @return 是否超时
*/
public isTimeout(): boolean {
let timestamp: number = new Date().getTime(); // 单位毫秒
return timestamp - this.startTime - this.timeout >= 0;
}
}
/**
* 超时回调
*/
export interface Callback {
/**
* Group请求超时回调
* @param group MGGroup对象
* @param callback 回调';
*/
onTimeout: (group: WDGroup, callback: Lego.Callback) => void;
}
}