2
2
3
3
const {
4
4
Promise,
5
+ PromisePrototypeFinally,
5
6
PromiseReject,
6
7
} = primordials ;
7
8
@@ -24,6 +25,13 @@ const lazyDOMException = hideStackFrames((message, name) => {
24
25
return new DOMException ( message , name ) ;
25
26
} ) ;
26
27
28
+ function cancelListenerHandler ( clear , reject ) {
29
+ if ( ! this . _destroyed ) {
30
+ clear ( this ) ;
31
+ reject ( lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
32
+ }
33
+ }
34
+
27
35
function setTimeout ( after , value , options = { } ) {
28
36
const args = value !== undefined ? [ value ] : value ;
29
37
if ( options == null || typeof options !== 'object' ) {
@@ -58,20 +66,21 @@ function setTimeout(after, value, options = {}) {
58
66
return PromiseReject (
59
67
lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
60
68
}
61
- return new Promise ( ( resolve , reject ) => {
69
+ let oncancel ;
70
+ const ret = new Promise ( ( resolve , reject ) => {
62
71
const timeout = new Timeout ( resolve , after , args , false , true ) ;
63
72
if ( ! ref ) timeout . unref ( ) ;
64
73
insert ( timeout , timeout . _idleTimeout ) ;
65
74
if ( signal ) {
66
- signal . addEventListener ( 'abort' , ( ) => {
67
- if ( ! timeout . _destroyed ) {
68
- // eslint-disable-next-line no-undef
69
- clearTimeout ( timeout ) ;
70
- reject ( lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
71
- }
72
- } , { once : true } ) ;
75
+ // eslint-disable-next-line no-undef
76
+ oncancel = cancelListenerHandler . bind ( timeout , clearTimeout , reject ) ;
77
+ signal . addEventListener ( 'abort' , oncancel ) ;
73
78
}
74
79
} ) ;
80
+ return oncancel !== undefined ?
81
+ PromisePrototypeFinally (
82
+ ret ,
83
+ ( ) => signal . removeEventListener ( 'abort' , oncancel ) ) : ret ;
75
84
}
76
85
77
86
function setImmediate ( value , options = { } ) {
@@ -107,19 +116,20 @@ function setImmediate(value, options = {}) {
107
116
return PromiseReject (
108
117
lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
109
118
}
110
- return new Promise ( ( resolve , reject ) => {
119
+ let oncancel ;
120
+ const ret = new Promise ( ( resolve , reject ) => {
111
121
const immediate = new Immediate ( resolve , [ value ] ) ;
112
122
if ( ! ref ) immediate . unref ( ) ;
113
123
if ( signal ) {
114
- signal . addEventListener ( 'abort' , ( ) => {
115
- if ( ! immediate . _destroyed ) {
116
- // eslint-disable-next-line no-undef
117
- clearImmediate ( immediate ) ;
118
- reject ( lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
119
- }
120
- } , { once : true } ) ;
124
+ // eslint-disable-next-line no-undef
125
+ oncancel = cancelListenerHandler . bind ( immediate , clearImmediate , reject ) ;
126
+ signal . addEventListener ( 'abort' , oncancel ) ;
121
127
}
122
128
} ) ;
129
+ return oncancel !== undefined ?
130
+ PromisePrototypeFinally (
131
+ ret ,
132
+ ( ) => signal . removeEventListener ( 'abort' , oncancel ) ) : ret ;
123
133
}
124
134
125
135
module . exports = {
0 commit comments