| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- class PriorityQueue {
- constructor( maxJobs = 6 ) {
- // options
- this.maxJobs = maxJobs;
- this.items = [];
- this.currJobs = 0;
- this.scheduled = false;
- }
- add( item, priority, callback ) {
- return new Promise( ( resolve, reject ) => {
- const prCallback = ( ...args ) => callback( ...args ).then( resolve ).catch( reject );
- const items = this.items;
- for ( let i = 0, l = items.length; i < l; i ++ ) {
- const thisItem = items[ i ];
- if ( thisItem.priority > priority ) {
- items.splice( i, 0, { priority, item, callback: prCallback } );
- this.scheduleJobRun();
- return;
- }
- }
- items.push( { priority, item, callback: prCallback } );
- this.scheduleJobRun();
- } );
- }
- remove( item ) {
- const items = this.items;
- for ( let i = 0, l = items.length; i < l; i ++ ) {
- const thisItem = items[ i ];
- if ( thisItem.item === item ) {
- items.splice( i, 1 );
- break;
- }
- }
- }
- tryRunJobs() {
- const items = this.items;
- const maxJobs = this.maxJobs;
- while ( maxJobs > this.currJobs && items.length > 0 ) {
- this.currJobs ++;
- const { item, priority, callback } = items.pop();
- callback( item, priority )
- .then( () => {
- this.currJobs --;
- this.scheduleJobRun();
- } )
- .catch( () => {
- this.currJobs --;
- this.scheduleJobRun();
- } );
- }
- }
- scheduleJobRun() {
- if ( ! this.scheduled ) {
- Promise.resolve().then( () => {
- this.tryRunJobs();
- this.scheduled = false;
- } );
- this.scheduled = true;
- }
- }
- }
- export { PriorityQueue };
|