import { AsyncIterableX } from '../asynciterablex' ; import { MonoTypeOperatorAsyncFunction } from '../../interfaces' ; import { AbortError , throwIfAborted } from '../../aborterror' ; export class DebounceAsyncIterable < TSource > extends AsyncIterableX < TSource > { private _source : AsyncIterable < TSource > ; private _time : number ; constructor ( source , time ) { super ( ) ; this . _source = source ; this . _time = time ; } async * [ Symbol . asyncIterator ] ( signal ? ) { throwIfAborted ( signal ) ; let done = false ; let reject = ( ) => { } ; let resolve = ( ) => { } ; let promise = new Promise < TSource > ( ( r1 , r2 ) => { resolve = r1 ; reject = r2 ; } ) ; ( async ( ) => { let id = null ; const emitValue = ( value ) => { id = null ; resolve ( value ) ; promise = new Promise < TSource > ( ( r1 , r2 ) => { resolve = r1 ; reject = r2 ; } ) ; } ; if ( signal ) { signal . addEventListener ( 'abort' , ( ) => { done = true ; if ( id ) { clearTimeout ( id ) ; } id = null ; reject ( new AbortError ( ) ) ; } , { once : true } ) ; } try { let result ; const it = this . _source [ Symbol . asyncIterator ] ( signal ) ; while ( ! done && ! ( result = await it . next ( ) ) . done && ! done ) { if ( id ) { clearTimeout ( id ) ; } id = setTimeout ( emitValue , this . _time , result . value ) ; } } catch ( e ) { reject ( e ) ; } done = true ; } ) ( ) ; while ( ! done ) { yield await promise ; } } } template TSource param { number } time returns { MonoTypeOperatorAsyncFunction < TSource > } export function debounce < TSource > ( time ) { return function debounceOperatorFunction ( source ) : AsyncIterableX < TSource > { return new DebounceAsyncIterable < TSource > ( source , time ) ; } ; }