22
33const {
44 Promise,
5+ PromisePrototypeFinally,
56 PromiseReject,
67} = primordials ;
78
@@ -24,6 +25,13 @@ const lazyDOMException = hideStackFrames((message, name) => {
2425 return new DOMException ( message , name ) ;
2526} ) ;
2627
28+ function cancelListenerHandler ( clear , reject ) {
29+ if ( ! this . _destroyed ) {
30+ clear ( this ) ;
31+ reject ( lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
32+ }
33+ }
34+
2735function setTimeout ( after , value , options = { } ) {
2836 const args = value !== undefined ? [ value ] : value ;
2937 if ( options == null || typeof options !== 'object' ) {
@@ -58,20 +66,21 @@ function setTimeout(after, value, options = {}) {
5866 return PromiseReject (
5967 lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
6068 }
61- return new Promise ( ( resolve , reject ) => {
69+ let oncancel ;
70+ const ret = new Promise ( ( resolve , reject ) => {
6271 const timeout = new Timeout ( resolve , after , args , false , true ) ;
6372 if ( ! ref ) timeout . unref ( ) ;
6473 insert ( timeout , timeout . _idleTimeout ) ;
6574 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 ) ;
7378 }
7479 } ) ;
80+ return oncancel !== undefined ?
81+ PromisePrototypeFinally (
82+ ret ,
83+ ( ) => signal . removeEventListener ( 'abort' , oncancel ) ) : ret ;
7584}
7685
7786function setImmediate ( value , options = { } ) {
@@ -107,19 +116,20 @@ function setImmediate(value, options = {}) {
107116 return PromiseReject (
108117 lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ) ;
109118 }
110- return new Promise ( ( resolve , reject ) => {
119+ let oncancel ;
120+ const ret = new Promise ( ( resolve , reject ) => {
111121 const immediate = new Immediate ( resolve , [ value ] ) ;
112122 if ( ! ref ) immediate . unref ( ) ;
113123 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 ) ;
121127 }
122128 } ) ;
129+ return oncancel !== undefined ?
130+ PromisePrototypeFinally (
131+ ret ,
132+ ( ) => signal . removeEventListener ( 'abort' , oncancel ) ) : ret ;
123133}
124134
125135module . exports = {
0 commit comments