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