single-async-queue.ts 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. /**
  2. * Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Adam Midlik <midlik@gmail.com>
  5. */
  6. /** Job queue that allows at most one running and one pending job.
  7. * A newly enqueued job will cancel any other pending jobs. */
  8. export class SingleAsyncQueue {
  9. private isRunning: boolean;
  10. private queue: { id: number, func: () => any }[];
  11. private counter: number;
  12. private log: boolean;
  13. constructor(log: boolean = false) {
  14. this.isRunning = false;
  15. this.queue = [];
  16. this.counter = 0;
  17. this.log = log;
  18. }
  19. enqueue(job: () => any) {
  20. if (this.log) console.log('SingleAsyncQueue enqueue', this.counter);
  21. this.queue[0] = { id: this.counter, func: job };
  22. this.counter++;
  23. this.run(); // do not await
  24. }
  25. private async run() {
  26. if (this.isRunning) return;
  27. const job = this.queue.pop();
  28. if (!job) return;
  29. this.isRunning = true;
  30. try {
  31. if (this.log) console.log('SingleAsyncQueue run', job.id);
  32. await job.func();
  33. if (this.log) console.log('SingleAsyncQueue complete', job.id);
  34. } finally {
  35. this.isRunning = false;
  36. this.run();
  37. }
  38. }
  39. }