11export 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+ }
1010}
1111
1212export 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
1616
17- ( cancelHandler : ( ) => void ) : void ;
17+ ( cancelHandler : ( ) => void ) : void
1818}
1919
2020export 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