mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
44 lines
1.1 KiB
TypeScript
44 lines
1.1 KiB
TypeScript
import { v4 as uuid } from 'uuid';
|
|
|
|
type Job<ResultType> = (() => PromiseLike<ResultType>) | (() => ResultType);
|
|
|
|
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;
|
|
}
|
|
}
|