You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			46 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			46 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			TypeScript
		
	
| import { v4 as uuid } from 'uuid';
 | |
| 
 | |
| type Job<ResultType> = (() => PromiseLike<ResultType>) | (() => ResultType);
 | |
| 
 | |
| // TODO: This needs to replace js/modules/job_queue.js
 | |
| export class JobQueue {
 | |
|   private pending?: Promise<any> = Promise.resolve();
 | |
|   private readonly jobs: Map<string, Promise<unknown>> = new Map();
 | |
| 
 | |
|   public has(id: string): boolean {
 | |
|     return this.jobs.has(id);
 | |
|   }
 | |
| 
 | |
|   public async add<Result>(job: Job<Result>): Promise<Result> {
 | |
|     const id = uuid();
 | |
| 
 | |
|     return this.addWithId(id, job);
 | |
|   }
 | |
| 
 | |
|   public async addWithId<Result>(id: string, job: Job<Result>): Promise<Result> {
 | |
|     if (this.jobs.has(id)) {
 | |
|       return this.jobs.get(id) as Promise<Result>;
 | |
|     }
 | |
| 
 | |
|     // tslint:disable-next-line: no-promise-as-boolean
 | |
|     const previous = this.pending || Promise.resolve();
 | |
|     this.pending = previous.then(job, job);
 | |
| 
 | |
|     const current = this.pending;
 | |
|     void current
 | |
|       .catch(() => {
 | |
|         // This is done to avoid UnhandledPromiseError
 | |
|       })
 | |
|       .finally(() => {
 | |
|         if (this.pending === current) {
 | |
|           delete this?.pending;
 | |
|         }
 | |
|         this.jobs.delete(id);
 | |
|       });
 | |
| 
 | |
|     this.jobs.set(id, current);
 | |
| 
 | |
|     return current;
 | |
|   }
 | |
| }
 |