Skip to content

Instantly share code, notes, and snippets.

@leostera
Last active February 21, 2022 09:56
Show Gist options
  • Select an option

  • Save leostera/affbf56e5cb1ea52c4035ec2dfdc3dea to your computer and use it in GitHub Desktop.

Select an option

Save leostera/affbf56e5cb1ea52c4035ec2dfdc3dea to your computer and use it in GitHub Desktop.

Revisions

  1. leostera revised this gist Feb 21, 2022. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions ExampleUsage.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    const queue = new ConcurrentQueue({
    maxConcurrency: 2
    });

    let delay = (ms: number) =>
    new Promise((resolve) => setTimeout(() => resolve(true), ms));

    let log = async (ms: number, msg: string) => {
    await delay(ms);
    console.log(msg);
    return msg;
    };

    let tasks: Task<String>[] = [
    async () => log(2000, "I'm (even later) task #1!"),
    async () => log(1000, "I'm (late) task #2!"),
    async () => log(300, "I'm task #3!"),
    async () => log(400, "I'm task #4!"),
    async () => log(200, "I'm task #5!"),
    async () => log(500, "I'm task #6!"),
    async () => log(50, "I'm task #7!"),
    async () => log(1, "I'm task #8!")
    ];

    let results = await queue.run(tasks);
    console.log("Results: ", results);
  2. leostera created this gist Feb 21, 2022.
    36 changes: 36 additions & 0 deletions ConcurrentQueue.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    type QueueOpts = {
    maxConcurrency: Number;
    };

    type Task<R> = () => Promise<R>;

    class ConcurrentQueue<R> {
    opts: QueueOpts = {
    maxConcurrency: 1
    };

    tasks: Task<R>[] = [];

    results: R[] = [];

    constructor(opts: QueueOpts) {
    this.opts = opts;
    }

    public async run(tasks: Task<R>[]): Promise<R[]> {
    this.tasks = tasks;
    const workers: Promise<R | "done">[] = new Array(this.opts.maxConcurrency)
    .fill(0)
    .map((_) => this.doWork());
    await Promise.all(workers);
    return this.results;
    }

    async doWork(): Promise<R | "done"> {
    let nextTask = this.tasks.shift();
    if (nextTask === undefined) return "done";
    let result = await nextTask();
    this.results.push(result);
    return this.doWork();
    }
    }