@@ -18,7 +18,11 @@ const {
1818 codes : { ERR_INVALID_ARG_TYPE }
1919} = require ( 'internal/errors' ) ;
2020
21- const { validateAbortSignal } = require ( 'internal/validators' ) ;
21+ const {
22+ validateAbortSignal,
23+ validateBoolean,
24+ validateObject,
25+ } = require ( 'internal/validators' ) ;
2226
2327function cancelListenerHandler ( clear , reject ) {
2428 if ( ! this . _destroyed ) {
@@ -111,7 +115,59 @@ function setImmediate(value, options = {}) {
111115 ( ) => signal . removeEventListener ( 'abort' , oncancel ) ) : ret ;
112116}
113117
118+ async function * setInterval ( after , value , options = { } ) {
119+ validateObject ( options , 'options' ) ;
120+ const { signal, ref = true } = options ;
121+ validateAbortSignal ( signal , 'options.signal' ) ;
122+ validateBoolean ( ref , 'options.ref' ) ;
123+
124+ if ( signal ?. aborted )
125+ throw new AbortError ( ) ;
126+
127+ let onCancel ;
128+ let interval ;
129+ try {
130+ let notYielded = 0 ;
131+ let callback ;
132+ interval = new Timeout ( ( ) => {
133+ notYielded ++ ;
134+ if ( callback ) {
135+ callback ( ) ;
136+ callback = undefined ;
137+ }
138+ } , after , undefined , true , true ) ;
139+ if ( ! ref ) interval . unref ( ) ;
140+ insert ( interval , interval . _idleTimeout ) ;
141+ if ( signal ) {
142+ onCancel = ( ) => {
143+ // eslint-disable-next-line no-undef
144+ clearInterval ( interval ) ;
145+ if ( callback ) {
146+ callback ( PromiseReject ( new AbortError ( ) ) ) ;
147+ callback = undefined ;
148+ }
149+ } ;
150+ signal . addEventListener ( 'abort' , onCancel , { once : true } ) ;
151+ }
152+
153+ while ( ! signal ?. aborted ) {
154+ if ( notYielded === 0 ) {
155+ await new Promise ( ( resolve ) => callback = resolve ) ;
156+ }
157+ for ( ; notYielded > 0 ; notYielded -- ) {
158+ yield value ;
159+ }
160+ }
161+ throw new AbortError ( ) ;
162+ } finally {
163+ // eslint-disable-next-line no-undef
164+ clearInterval ( interval ) ;
165+ signal ?. removeEventListener ( 'abort' , onCancel ) ;
166+ }
167+ }
168+
114169module . exports = {
115170 setTimeout,
116171 setImmediate,
172+ setInterval,
117173} ;
0 commit comments