queue.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. class Queue<T extends { run: () => Promise<any> }> {
  2. private current?: Node<T>;
  3. private end?: Node<T>;
  4. private status: "waiting" | "running" = "waiting";
  5. append(item: T, autoRun = true) {
  6. const node = new Node(item);
  7. if (!this.current || !this.end) {
  8. this.current = this.end = node;
  9. } else {
  10. this.end.setNext(node);
  11. this.end = node;
  12. }
  13. if (autoRun) {
  14. this.startRun();
  15. }
  16. }
  17. startRun() {
  18. if (this.status === "waiting") {
  19. this.run();
  20. }
  21. }
  22. async run() {
  23. if (this.current) {
  24. this.status = "running";
  25. const current = this.current;
  26. const self = current.getSelf();
  27. this.current = this.current.getNext();
  28. const res = await self.run();
  29. current.destroy();
  30. if (res === false) {
  31. this.status = "waiting";
  32. } else {
  33. this.run();
  34. }
  35. } else {
  36. this.end = undefined;
  37. this.status = "waiting";
  38. }
  39. }
  40. }
  41. class Node<T = any> {
  42. private prev?: Node<T>;
  43. private next?: Node<T>;
  44. private self: T;
  45. constructor(self: T) {
  46. this.self = self;
  47. }
  48. getSelf() {
  49. return this.self;
  50. }
  51. setPrev(prev?: Node<T>) {
  52. this.prev = prev;
  53. if (prev) {
  54. prev.next = this;
  55. }
  56. }
  57. setNext(next?: Node<T>) {
  58. this.next = next;
  59. if (next) {
  60. next.prev = this;
  61. }
  62. }
  63. getPrev() {
  64. return this.prev;
  65. }
  66. getNext() {
  67. return this.next;
  68. }
  69. destroy() {
  70. if (this.prev) {
  71. this.prev.setNext(undefined);
  72. }
  73. if (this.next) {
  74. this.next.setPrev(undefined);
  75. }
  76. this.prev = undefined;
  77. this.next = undefined;
  78. this.self = undefined;
  79. }
  80. }
  81. export { Queue };