export class ImageWriteQueue { private readonly maxConcurrent = 3 ; private readonly pendingImages : Array < { key : number ; buffer : Buffer ; } > = [ ] ; private inProgress : number [ ] = [ ] ; constructor ( private readonly fillImage ) { } public abort ( ) { this . pendingImages . splice ( 0 , this . pendingImages . length ) ; } public queue ( key , buffer ) { let updated = false ; for ( const img of this . pendingImages ) { if ( img . key === key ) { img . buffer = buffer ; updated = true ; break ; } } if ( ! updated ) { this . pendingImages . push ( { key : key , buffer : buffer } ) ; } this . tryDequeue ( ) ; } private tryDequeue ( ) { if ( this . inProgress . length <= this . maxConcurrent && this . pendingImages . length > 0 ) { const nextImageIndex = this . pendingImages . findIndex ( ( img ) => this . inProgress . indexOf ( img . key ) === - 1 ) ; if ( nextImageIndex === - 1 ) { return ; } const nextImage = this . pendingImages [ nextImageIndex ] ; this . pendingImages . splice ( nextImageIndex , 1 ) ; if ( ! nextImage ) { return ; } this . inProgress . push ( nextImage . key ) ; this . fillImage ( nextImage . key , nextImage . buffer ) . catch ( ( e ) => { console . error ( 'fillImage error:' , e ) ; } ) . then ( ( ) => { this . inProgress = this . inProgress . filter ( ( k ) => k !== nextImage . key ) ; setImmediate ( ( ) => { this . tryDequeue ( ) ; } ) ; } ) ; } } }