-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
149 lines (130 loc) · 2.21 KB
/
index.ts
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
/**
* Promise manageable from outer scope
*/
export default class PromiseSource<TResult = void>
{
/**
* Promise
* @internal
*/
private readonly _promise: Promise<TResult>;
/**
* Resolve callback
* @internal
*/
private _resolve: (value?: (PromiseLike<TResult> | TResult)) => void;
/**
* Reject callback
* @internal
*/
private _reject: (reason?: any) => void;
/**
* Set after resolve
* @internal
*/
private _resolved: boolean;
/**
* Set after reject
* @internal
*/
private _rejected: boolean;
/**
* Timeout identifier
* @internal
*/
private _timeout?: number;
/**
* Get managed Promise
*/
public get promise(): Promise<TResult>
{
return this._promise;
}
/**
* True when managed promise was resolved
*/
public get resolved(): boolean
{
return this._resolved;
}
/**
* True when managed promise was rejected
*/
public get rejected(): boolean
{
return this._rejected;
}
/**
* True when resolved or rejected
*/
public get completed()
{
return this._rejected || this._resolved;
}
/**
* Ctor
* @param {number} [timeout] Optional timeout
*/
constructor(timeout?: number)
{
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
})
if (timeout != undefined)
{
this._timeout = setTimeout(() => {
if (!this.completed)
{
this.reject(new Error("Promise timed out"));
}
}, ~~timeout);
}
}
/**
* Reject managed promise
* @param reason
*/
public reject(reason?: any)
{
this.validateCompletion();
this._reject(reason);
this._rejected = true;
this.dispose();
}
/**
* Resolve managed promise
* @param value
*/
public resolve(value?: TResult)
{
this._resolve(value);
this._resolved = true;
this.dispose();
}
/**
* Clear handlers
* @internal
*/
private dispose()
{
this._resolve = undefined;
this._reject = undefined;
if (this._timeout != undefined)
{
clearTimeout(this._timeout);
this._timeout = undefined;
}
}
/**
* Validate completion
* @internal
*/
private validateCompletion()
{
if (this.completed)
{
throw Error("PromiseSource was already " + (this._rejected ? "rejected" : "resolved") + ".");
}
}
}