asyncTaskManager.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.AsyncTaskManager = void 0;
  4. const log_1 = require("./log");
  5. const promise_1 = require("./promise");
  6. class AsyncTaskManager {
  7. constructor(cancellationToken) {
  8. this.cancellationToken = cancellationToken;
  9. this.tasks = [];
  10. this.errors = [];
  11. }
  12. add(task) {
  13. if (this.cancellationToken == null || !this.cancellationToken.cancelled) {
  14. this.addTask(task());
  15. }
  16. }
  17. addTask(promise) {
  18. if (this.cancellationToken.cancelled) {
  19. log_1.log.debug({ reason: "cancelled", stack: new Error().stack }, "async task not added");
  20. if ("cancel" in promise) {
  21. ;
  22. promise.cancel();
  23. }
  24. return;
  25. }
  26. this.tasks.push(promise.catch(it => {
  27. log_1.log.debug({ error: it.message || it.toString() }, "async task error");
  28. this.errors.push(it);
  29. return Promise.resolve(null);
  30. }));
  31. }
  32. cancelTasks() {
  33. for (const task of this.tasks) {
  34. if ("cancel" in task) {
  35. ;
  36. task.cancel();
  37. }
  38. }
  39. this.tasks.length = 0;
  40. }
  41. async awaitTasks() {
  42. if (this.cancellationToken.cancelled) {
  43. this.cancelTasks();
  44. return [];
  45. }
  46. const checkErrors = () => {
  47. if (this.errors.length > 0) {
  48. this.cancelTasks();
  49. throwError(this.errors);
  50. return;
  51. }
  52. };
  53. checkErrors();
  54. let result = null;
  55. const tasks = this.tasks;
  56. let list = tasks.slice();
  57. tasks.length = 0;
  58. while (list.length > 0) {
  59. const subResult = await Promise.all(list);
  60. result = result == null ? subResult : result.concat(subResult);
  61. checkErrors();
  62. if (tasks.length === 0) {
  63. break;
  64. }
  65. else {
  66. if (this.cancellationToken.cancelled) {
  67. this.cancelTasks();
  68. return [];
  69. }
  70. list = tasks.slice();
  71. tasks.length = 0;
  72. }
  73. }
  74. return result || [];
  75. }
  76. }
  77. exports.AsyncTaskManager = AsyncTaskManager;
  78. function throwError(errors) {
  79. if (errors.length === 1) {
  80. throw errors[0];
  81. }
  82. else if (errors.length > 1) {
  83. throw new promise_1.NestedError(errors, "Cannot cleanup: ");
  84. }
  85. }
  86. //# sourceMappingURL=asyncTaskManager.js.map