1
1
export class CancelError extends Error {
2
- constructor ( message : string ) {
3
- super ( message )
4
- this . name = " CancelError"
5
- }
6
-
7
- public get isCancelled ( ) : boolean {
8
- return true
9
- }
2
+ constructor ( message : string ) {
3
+ super ( message ) ;
4
+ this . name = ' CancelError' ;
5
+ }
6
+
7
+ public get isCancelled ( ) : boolean {
8
+ return true ;
9
+ }
10
10
}
11
11
12
12
export interface OnCancel {
13
- readonly isResolved : boolean
14
- readonly isRejected : boolean
15
- readonly isCancelled : boolean
13
+ readonly isResolved : boolean ;
14
+ readonly isRejected : boolean ;
15
+ readonly isCancelled : boolean ;
16
16
17
- ( cancelHandler : ( ) => void ) : void
17
+ ( cancelHandler : ( ) => void ) : void ;
18
18
}
19
19
20
20
export class CancelablePromise < T > implements Promise < T > {
21
- private _isResolved : boolean
22
- private _isRejected : boolean
23
- private _isCancelled : boolean
24
- readonly cancelHandlers : ( ( ) => void ) [ ]
25
- readonly promise : Promise < T >
26
- private _resolve ?: ( value : T | PromiseLike < T > ) => void
27
- private _reject ?: ( reason ?: unknown ) => void
28
-
29
- constructor (
30
- executor : (
31
- resolve : ( value : T | PromiseLike < T > ) => void ,
32
- reject : ( reason ?: unknown ) => void ,
33
- onCancel : OnCancel ,
34
- ) => void ,
35
- ) {
36
- this . _isResolved = false
37
- this . _isRejected = false
38
- this . _isCancelled = false
39
- this . cancelHandlers = [ ]
40
- this . promise = new Promise < T > ( ( resolve , reject ) => {
41
- this . _resolve = resolve
42
- this . _reject = reject
43
-
44
- const onResolve = ( value : T | PromiseLike < T > ) : void => {
45
- if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
46
- return
47
- }
48
- this . _isResolved = true
49
- if ( this . _resolve ) this . _resolve ( value )
50
- }
51
-
52
- const onReject = ( reason ?: unknown ) : void => {
53
- if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
54
- return
55
- }
56
- this . _isRejected = true
57
- if ( this . _reject ) this . _reject ( reason )
58
- }
59
-
60
- const onCancel = ( cancelHandler : ( ) => void ) : void => {
61
- if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
62
- return
63
- }
64
- this . cancelHandlers . push ( cancelHandler )
65
- }
66
-
67
- Object . defineProperty ( onCancel , " isResolved" , {
68
- get : ( ) : boolean => this . _isResolved ,
69
- } )
70
-
71
- Object . defineProperty ( onCancel , " isRejected" , {
72
- get : ( ) : boolean => this . _isRejected ,
73
- } )
74
-
75
- Object . defineProperty ( onCancel , " isCancelled" , {
76
- get : ( ) : boolean => this . _isCancelled ,
77
- } )
78
-
79
- return executor ( onResolve , onReject , onCancel as OnCancel )
80
- } )
81
- }
82
-
83
- get [ Symbol . toStringTag ] ( ) {
84
- return "Cancellable Promise"
85
- }
86
-
87
- public then < TResult1 = T , TResult2 = never > (
88
- onFulfilled ?: ( ( value : T ) => TResult1 | PromiseLike < TResult1 > ) | null ,
89
- onRejected ?: ( ( reason : unknown ) => TResult2 | PromiseLike < TResult2 > ) | null ,
90
- ) : Promise < TResult1 | TResult2 > {
91
- return this . promise . then ( onFulfilled , onRejected )
92
- }
93
-
94
- public catch < TResult = never > (
95
- onRejected ?: ( ( reason : unknown ) => TResult | PromiseLike < TResult > ) | null ,
96
- ) : Promise < T | TResult > {
97
- return this . promise . catch ( onRejected )
98
- }
99
-
100
- public finally ( onFinally ?: ( ( ) => void ) | null ) : Promise < T > {
101
- return this . promise . finally ( onFinally )
102
- }
103
-
104
- public cancel ( ) : void {
105
- if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
106
- return
107
- }
108
- this . _isCancelled = true
109
- if ( this . cancelHandlers . length ) {
110
- try {
111
- for ( const cancelHandler of this . cancelHandlers ) {
112
- cancelHandler ( )
113
- }
114
- } catch ( error ) {
115
- console . warn ( " Cancellation threw an error" , error )
116
- return
117
- }
118
- }
119
- this . cancelHandlers . length = 0
120
- if ( this . _reject ) this . _reject ( new CancelError ( " Request aborted" ) )
121
- }
122
-
123
- public get isCancelled ( ) : boolean {
124
- return this . _isCancelled
125
- }
126
- }
21
+ private _isResolved : boolean ;
22
+ private _isRejected : boolean ;
23
+ private _isCancelled : boolean ;
24
+ readonly cancelHandlers : ( ( ) => void ) [ ] ;
25
+ readonly promise : Promise < T > ;
26
+ private _resolve ?: ( value : T | PromiseLike < T > ) => void ;
27
+ private _reject ?: ( reason ?: unknown ) => void ;
28
+
29
+ constructor (
30
+ executor : (
31
+ resolve : ( value : T | PromiseLike < T > ) => void ,
32
+ reject : ( reason ?: unknown ) => void ,
33
+ onCancel : OnCancel
34
+ ) => void
35
+ ) {
36
+ this . _isResolved = false ;
37
+ this . _isRejected = false ;
38
+ this . _isCancelled = false ;
39
+ this . cancelHandlers = [ ] ;
40
+ this . promise = new Promise < T > ( ( resolve , reject ) => {
41
+ this . _resolve = resolve ;
42
+ this . _reject = reject ;
43
+
44
+ const onResolve = ( value : T | PromiseLike < T > ) : void => {
45
+ if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
46
+ return ;
47
+ }
48
+ this . _isResolved = true ;
49
+ if ( this . _resolve ) this . _resolve ( value ) ;
50
+ } ;
51
+
52
+ const onReject = ( reason ?: unknown ) : void => {
53
+ if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
54
+ return ;
55
+ }
56
+ this . _isRejected = true ;
57
+ if ( this . _reject ) this . _reject ( reason ) ;
58
+ } ;
59
+
60
+ const onCancel = ( cancelHandler : ( ) => void ) : void => {
61
+ if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
62
+ return ;
63
+ }
64
+ this . cancelHandlers . push ( cancelHandler ) ;
65
+ } ;
66
+
67
+ Object . defineProperty ( onCancel , ' isResolved' , {
68
+ get : ( ) : boolean => this . _isResolved ,
69
+ } ) ;
70
+
71
+ Object . defineProperty ( onCancel , ' isRejected' , {
72
+ get : ( ) : boolean => this . _isRejected ,
73
+ } ) ;
74
+
75
+ Object . defineProperty ( onCancel , ' isCancelled' , {
76
+ get : ( ) : boolean => this . _isCancelled ,
77
+ } ) ;
78
+
79
+ return executor ( onResolve , onReject , onCancel as OnCancel ) ;
80
+ } ) ;
81
+ }
82
+
83
+ get [ Symbol . toStringTag ] ( ) {
84
+ return "Cancellable Promise" ;
85
+ }
86
+
87
+ public then < TResult1 = T , TResult2 = never > (
88
+ onFulfilled ?: ( ( value : T ) => TResult1 | PromiseLike < TResult1 > ) | null ,
89
+ onRejected ?: ( ( reason : unknown ) => TResult2 | PromiseLike < TResult2 > ) | null
90
+ ) : Promise < TResult1 | TResult2 > {
91
+ return this . promise . then ( onFulfilled , onRejected ) ;
92
+ }
93
+
94
+ public catch < TResult = never > (
95
+ onRejected ?: ( ( reason : unknown ) => TResult | PromiseLike < TResult > ) | null
96
+ ) : Promise < T | TResult > {
97
+ return this . promise . catch ( onRejected ) ;
98
+ }
99
+
100
+ public finally ( onFinally ?: ( ( ) => void ) | null ) : Promise < T > {
101
+ return this . promise . finally ( onFinally ) ;
102
+ }
103
+
104
+ public cancel ( ) : void {
105
+ if ( this . _isResolved || this . _isRejected || this . _isCancelled ) {
106
+ return ;
107
+ }
108
+ this . _isCancelled = true ;
109
+ if ( this . cancelHandlers . length ) {
110
+ try {
111
+ for ( const cancelHandler of this . cancelHandlers ) {
112
+ cancelHandler ( ) ;
113
+ }
114
+ } catch ( error ) {
115
+ console . warn ( ' Cancellation threw an error' , error ) ;
116
+ return ;
117
+ }
118
+ }
119
+ this . cancelHandlers . length = 0 ;
120
+ if ( this . _reject ) this . _reject ( new CancelError ( ' Request aborted' ) ) ;
121
+ }
122
+
123
+ public get isCancelled ( ) : boolean {
124
+ return this . _isCancelled ;
125
+ }
126
+ }
0 commit comments