@tmagic/editor 1.8.0-beta.17 → 1.8.0-beta.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/style.css CHANGED
@@ -70,7 +70,7 @@
70
70
  }
71
71
  .tmagic-design-card.tmagic-design-card--flat .el-card__header {
72
72
  border-bottom: none;
73
- padding: 8px 16px;
73
+ padding: 16px;
74
74
  }
75
75
  .tmagic-design-card.tmagic-design-card--flat .el-card__header:hover {
76
76
  background: transparent;
@@ -85,7 +85,7 @@
85
85
  padding: 0 16px 0 16px;
86
86
  }
87
87
  .tmagic-design-card.tmagic-design-card--flat .el-card__body .tmagic-design-form-item:not(tbody .tmagic-design-form-item) {
88
- margin-bottom: 8px;
88
+ margin-bottom: 16px;
89
89
  }
90
90
  .tmagic-design-card.tmagic-design-card--flat .el-card__body > .m-container-row {
91
91
  overflow-x: hidden;
@@ -1935,26 +1935,29 @@ fieldset.m-fieldset .m-form-tip {
1935
1935
  border: 0 !important;
1936
1936
  }
1937
1937
  .m-fields-code-select .el-card__body .tmagic-design-form-item {
1938
- margin-bottom: 18px;
1938
+ margin-bottom: 16px;
1939
1939
  }
1940
1940
  .m-fields-code-select .code-select-content > .m-fields-group-list > .tmagic-design-card--flat > .el-card__header {
1941
- padding: 8px 0;
1941
+ padding: 16px 0;
1942
1942
  }
1943
1943
  .m-fields-code-select .create-button.fullWidth {
1944
1944
  width: 100%;
1945
- margin: 0 0 8px 0;
1945
+ margin: 0 0 16px 0;
1946
1946
  }
1947
1947
 
1948
1948
  .m-fields-event-select {
1949
1949
  width: 100%;
1950
1950
  }
1951
1951
  .m-fields-event-select .fullWidth {
1952
- width: calc(100% - 32px);
1952
+ width: 100%;
1953
1953
  box-sizing: border-box;
1954
1954
  }
1955
1955
  .m-fields-event-select .fullWidth.create-button {
1956
1956
  width: 100%;
1957
1957
  }
1958
+ .m-fields-event-select .fullWidth.m-container-ui-event {
1959
+ width: calc(100% - 32px);
1960
+ }
1958
1961
  .m-fields-event-select .event-select-container {
1959
1962
  padding: 0 16px;
1960
1963
  }
@@ -1962,13 +1965,13 @@ fieldset.m-fieldset .m-form-tip {
1962
1965
  border-bottom: 1px solid #ebeef5;
1963
1966
  }
1964
1967
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body {
1965
- padding-bottom: 8px;
1968
+ padding-bottom: 16px;
1966
1969
  }
1967
1970
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body .m-fields-group-list-footer div {
1968
1971
  justify-content: flex-start !important;
1969
1972
  }
1970
1973
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body .el-card.tmagic-design-card--flat > .el-card__header {
1971
- padding: 8px 0;
1974
+ padding: 16px 0;
1972
1975
  }
1973
1976
  .m-fields-event-select .event-select-code {
1974
1977
  margin-left: 20px;
@@ -1,3 +1,4 @@
1
+ import { error } from "../logger.js";
1
2
  import { EventEmitter } from "events";
2
3
  //#region packages/editor/src/utils/dep/idle-task.ts
3
4
  globalThis.requestIdleCallback = globalThis.requestIdleCallback || function(cb) {
@@ -35,7 +36,7 @@ var IdleTask = class extends EventEmitter {
35
36
  this.taskList = [];
36
37
  this.taskHandle = null;
37
38
  this.emit("update-task-length", {
38
- length: this.taskList.length + this.hightLevelTaskList.length,
39
+ length: this.getTaskLength(),
39
40
  hightLevelLength: this.hightLevelTaskList.length
40
41
  });
41
42
  }
@@ -49,30 +50,51 @@ var IdleTask = class extends EventEmitter {
49
50
  return super.emit(eventName, ...args);
50
51
  }
51
52
  runTaskQueue(deadline) {
52
- const { hightLevelTaskList, taskList } = this;
53
- while (deadline.timeRemaining() > 0 && (taskList.length || hightLevelTaskList.length)) {
54
- const timeRemaining = deadline.timeRemaining();
55
- let times = 0;
56
- if (timeRemaining <= 5) times = 10;
57
- else if (timeRemaining <= 10) times = 100;
58
- else if (timeRemaining <= 15) times = 300;
59
- else times = 600;
60
- for (let i = 0; i < times; i++) {
61
- const task = hightLevelTaskList.length > 0 ? hightLevelTaskList.shift() : taskList.shift();
62
- if (task) task.handler(task.data);
63
- if (hightLevelTaskList.length === 0 && taskList.length === 0) break;
53
+ this.taskHandle = null;
54
+ try {
55
+ while (deadline.timeRemaining() > 0 && this.getTaskLength()) {
56
+ const timeRemaining = deadline.timeRemaining();
57
+ let times = 0;
58
+ if (timeRemaining <= 5) times = 10;
59
+ else if (timeRemaining <= 10) times = 100;
60
+ else if (timeRemaining <= 15) times = 300;
61
+ else times = 600;
62
+ for (let i = 0; i < times; i++) {
63
+ const task = this.hightLevelTaskList.length > 0 ? this.hightLevelTaskList.shift() : this.taskList.shift();
64
+ if (task) this.runTask(task);
65
+ if (!this.getTaskLength()) break;
66
+ }
64
67
  }
68
+ } finally {
69
+ this.finishRun();
65
70
  }
66
- if (!hightLevelTaskList.length) this.emit("hight-level-finish");
67
- if (hightLevelTaskList.length || taskList.length) this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
68
- else {
69
- this.taskHandle = 0;
70
- this.emit("finish");
71
+ }
72
+ /**
73
+ * 单个任务失败不能中断整个队列,否则后续任务永远不会被执行,
74
+ * 依赖收集会停在半路(收集中状态与剩余任务数都不再变化)
75
+ */
76
+ runTask(task) {
77
+ try {
78
+ task.handler(task.data);
79
+ } catch (e) {
80
+ error("magic editor: 空闲任务执行失败", e);
71
81
  }
72
- this.emit("update-task-length", {
73
- length: taskList.length + hightLevelTaskList.length,
74
- hightLevelLength: hightLevelTaskList.length
75
- });
82
+ }
83
+ finishRun() {
84
+ try {
85
+ if (!this.hightLevelTaskList.length) this.emit("hight-level-finish");
86
+ } finally {
87
+ if (this.getTaskLength()) {
88
+ if (!this.taskHandle) this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
89
+ } else this.emit("finish");
90
+ this.emit("update-task-length", {
91
+ length: this.getTaskLength(),
92
+ hightLevelLength: this.hightLevelTaskList.length
93
+ });
94
+ }
95
+ }
96
+ getTaskLength() {
97
+ return this.taskList.length + this.hightLevelTaskList.length;
76
98
  }
77
99
  };
78
100
  //#endregion
package/dist/style.css CHANGED
@@ -70,7 +70,7 @@
70
70
  }
71
71
  .tmagic-design-card.tmagic-design-card--flat .el-card__header {
72
72
  border-bottom: none;
73
- padding: 8px 16px;
73
+ padding: 16px;
74
74
  }
75
75
  .tmagic-design-card.tmagic-design-card--flat .el-card__header:hover {
76
76
  background: transparent;
@@ -85,7 +85,7 @@
85
85
  padding: 0 16px 0 16px;
86
86
  }
87
87
  .tmagic-design-card.tmagic-design-card--flat .el-card__body .tmagic-design-form-item:not(tbody .tmagic-design-form-item) {
88
- margin-bottom: 8px;
88
+ margin-bottom: 16px;
89
89
  }
90
90
  .tmagic-design-card.tmagic-design-card--flat .el-card__body > .m-container-row {
91
91
  overflow-x: hidden;
@@ -1935,26 +1935,29 @@ fieldset.m-fieldset .m-form-tip {
1935
1935
  border: 0 !important;
1936
1936
  }
1937
1937
  .m-fields-code-select .el-card__body .tmagic-design-form-item {
1938
- margin-bottom: 18px;
1938
+ margin-bottom: 16px;
1939
1939
  }
1940
1940
  .m-fields-code-select .code-select-content > .m-fields-group-list > .tmagic-design-card--flat > .el-card__header {
1941
- padding: 8px 0;
1941
+ padding: 16px 0;
1942
1942
  }
1943
1943
  .m-fields-code-select .create-button.fullWidth {
1944
1944
  width: 100%;
1945
- margin: 0 0 8px 0;
1945
+ margin: 0 0 16px 0;
1946
1946
  }
1947
1947
 
1948
1948
  .m-fields-event-select {
1949
1949
  width: 100%;
1950
1950
  }
1951
1951
  .m-fields-event-select .fullWidth {
1952
- width: calc(100% - 32px);
1952
+ width: 100%;
1953
1953
  box-sizing: border-box;
1954
1954
  }
1955
1955
  .m-fields-event-select .fullWidth.create-button {
1956
1956
  width: 100%;
1957
1957
  }
1958
+ .m-fields-event-select .fullWidth.m-container-ui-event {
1959
+ width: calc(100% - 32px);
1960
+ }
1958
1961
  .m-fields-event-select .event-select-container {
1959
1962
  padding: 0 16px;
1960
1963
  }
@@ -1962,13 +1965,13 @@ fieldset.m-fieldset .m-form-tip {
1962
1965
  border-bottom: 1px solid #ebeef5;
1963
1966
  }
1964
1967
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body {
1965
- padding-bottom: 8px;
1968
+ padding-bottom: 16px;
1966
1969
  }
1967
1970
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body .m-fields-group-list-footer div {
1968
1971
  justify-content: flex-start !important;
1969
1972
  }
1970
1973
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body .el-card.tmagic-design-card--flat > .el-card__header {
1971
- padding: 8px 0;
1974
+ padding: 16px 0;
1972
1975
  }
1973
1976
  .m-fields-event-select .event-select-code {
1974
1977
  margin-left: 20px;
@@ -70,7 +70,7 @@
70
70
  }
71
71
  .tmagic-design-card.tmagic-design-card--flat .el-card__header {
72
72
  border-bottom: none;
73
- padding: 8px 16px;
73
+ padding: 16px;
74
74
  }
75
75
  .tmagic-design-card.tmagic-design-card--flat .el-card__header:hover {
76
76
  background: transparent;
@@ -85,7 +85,7 @@
85
85
  padding: 0 16px 0 16px;
86
86
  }
87
87
  .tmagic-design-card.tmagic-design-card--flat .el-card__body .tmagic-design-form-item:not(tbody .tmagic-design-form-item) {
88
- margin-bottom: 8px;
88
+ margin-bottom: 16px;
89
89
  }
90
90
  .tmagic-design-card.tmagic-design-card--flat .el-card__body > .m-container-row {
91
91
  overflow-x: hidden;
@@ -2025,26 +2025,29 @@ fieldset.m-fieldset .m-form-tip {
2025
2025
  border: 0 !important;
2026
2026
  }
2027
2027
  .m-fields-code-select .el-card__body .tmagic-design-form-item {
2028
- margin-bottom: 18px;
2028
+ margin-bottom: 16px;
2029
2029
  }
2030
2030
  .m-fields-code-select .code-select-content > .m-fields-group-list > .tmagic-design-card--flat > .el-card__header {
2031
- padding: 8px 0;
2031
+ padding: 16px 0;
2032
2032
  }
2033
2033
  .m-fields-code-select .create-button.fullWidth {
2034
2034
  width: 100%;
2035
- margin: 0 0 8px 0;
2035
+ margin: 0 0 16px 0;
2036
2036
  }
2037
2037
 
2038
2038
  .m-fields-event-select {
2039
2039
  width: 100%;
2040
2040
  }
2041
2041
  .m-fields-event-select .fullWidth {
2042
- width: calc(100% - 32px);
2042
+ width: 100%;
2043
2043
  box-sizing: border-box;
2044
2044
  }
2045
2045
  .m-fields-event-select .fullWidth.create-button {
2046
2046
  width: 100%;
2047
2047
  }
2048
+ .m-fields-event-select .fullWidth.m-container-ui-event {
2049
+ width: calc(100% - 32px);
2050
+ }
2048
2051
  .m-fields-event-select .event-select-container {
2049
2052
  padding: 0 16px;
2050
2053
  }
@@ -2052,13 +2055,13 @@ fieldset.m-fieldset .m-form-tip {
2052
2055
  border-bottom: 1px solid #ebeef5;
2053
2056
  }
2054
2057
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body {
2055
- padding-bottom: 8px;
2058
+ padding-bottom: 16px;
2056
2059
  }
2057
2060
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body .m-fields-group-list-footer div {
2058
2061
  justify-content: flex-start !important;
2059
2062
  }
2060
2063
  .m-fields-event-select .event-select-container > .el-card.tmagic-design-card--flat > .el-card__body .el-card.tmagic-design-card--flat > .el-card__header {
2061
- padding: 8px 0;
2064
+ padding: 16px 0;
2062
2065
  }
2063
2066
  .m-fields-event-select .event-select-code {
2064
2067
  margin-left: 20px;
@@ -9680,7 +9680,7 @@
9680
9680
  this.taskList = [];
9681
9681
  this.taskHandle = null;
9682
9682
  this.emit("update-task-length", {
9683
- length: this.taskList.length + this.hightLevelTaskList.length,
9683
+ length: this.getTaskLength(),
9684
9684
  hightLevelLength: this.hightLevelTaskList.length
9685
9685
  });
9686
9686
  }
@@ -9694,30 +9694,51 @@
9694
9694
  return super.emit(eventName, ...args);
9695
9695
  }
9696
9696
  runTaskQueue(deadline) {
9697
- const { hightLevelTaskList, taskList } = this;
9698
- while (deadline.timeRemaining() > 0 && (taskList.length || hightLevelTaskList.length)) {
9699
- const timeRemaining = deadline.timeRemaining();
9700
- let times = 0;
9701
- if (timeRemaining <= 5) times = 10;
9702
- else if (timeRemaining <= 10) times = 100;
9703
- else if (timeRemaining <= 15) times = 300;
9704
- else times = 600;
9705
- for (let i = 0; i < times; i++) {
9706
- const task = hightLevelTaskList.length > 0 ? hightLevelTaskList.shift() : taskList.shift();
9707
- if (task) task.handler(task.data);
9708
- if (hightLevelTaskList.length === 0 && taskList.length === 0) break;
9697
+ this.taskHandle = null;
9698
+ try {
9699
+ while (deadline.timeRemaining() > 0 && this.getTaskLength()) {
9700
+ const timeRemaining = deadline.timeRemaining();
9701
+ let times = 0;
9702
+ if (timeRemaining <= 5) times = 10;
9703
+ else if (timeRemaining <= 10) times = 100;
9704
+ else if (timeRemaining <= 15) times = 300;
9705
+ else times = 600;
9706
+ for (let i = 0; i < times; i++) {
9707
+ const task = this.hightLevelTaskList.length > 0 ? this.hightLevelTaskList.shift() : this.taskList.shift();
9708
+ if (task) this.runTask(task);
9709
+ if (!this.getTaskLength()) break;
9710
+ }
9709
9711
  }
9712
+ } finally {
9713
+ this.finishRun();
9710
9714
  }
9711
- if (!hightLevelTaskList.length) this.emit("hight-level-finish");
9712
- if (hightLevelTaskList.length || taskList.length) this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
9713
- else {
9714
- this.taskHandle = 0;
9715
- this.emit("finish");
9715
+ }
9716
+ /**
9717
+ * 单个任务失败不能中断整个队列,否则后续任务永远不会被执行,
9718
+ * 依赖收集会停在半路(收集中状态与剩余任务数都不再变化)
9719
+ */
9720
+ runTask(task) {
9721
+ try {
9722
+ task.handler(task.data);
9723
+ } catch (e) {
9724
+ error("magic editor: 空闲任务执行失败", e);
9716
9725
  }
9717
- this.emit("update-task-length", {
9718
- length: taskList.length + hightLevelTaskList.length,
9719
- hightLevelLength: hightLevelTaskList.length
9720
- });
9726
+ }
9727
+ finishRun() {
9728
+ try {
9729
+ if (!this.hightLevelTaskList.length) this.emit("hight-level-finish");
9730
+ } finally {
9731
+ if (this.getTaskLength()) {
9732
+ if (!this.taskHandle) this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
9733
+ } else this.emit("finish");
9734
+ this.emit("update-task-length", {
9735
+ length: this.getTaskLength(),
9736
+ hightLevelLength: this.hightLevelTaskList.length
9737
+ });
9738
+ }
9739
+ }
9740
+ getTaskLength() {
9741
+ return this.taskList.length + this.hightLevelTaskList.length;
9721
9742
  }
9722
9743
  };
9723
9744
  //#endregion
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.8.0-beta.17",
2
+ "version": "1.8.0-beta.18",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -58,11 +58,11 @@
58
58
  "moveable": "^0.53.0",
59
59
  "serialize-javascript": "^7.0.0",
60
60
  "sortablejs": "^1.15.6",
61
- "@tmagic/form": "1.8.0-beta.17",
62
- "@tmagic/design": "1.8.0-beta.17",
63
- "@tmagic/utils": "1.8.0-beta.17",
64
- "@tmagic/table": "1.8.0-beta.17",
65
- "@tmagic/stage": "1.8.0-beta.17"
61
+ "@tmagic/design": "1.8.0-beta.18",
62
+ "@tmagic/form": "1.8.0-beta.18",
63
+ "@tmagic/stage": "1.8.0-beta.18",
64
+ "@tmagic/table": "1.8.0-beta.18",
65
+ "@tmagic/utils": "1.8.0-beta.18"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/events": "^3.0.3",
@@ -76,7 +76,7 @@
76
76
  "type-fest": "^5.2.0",
77
77
  "typescript": "^6.0.3",
78
78
  "vue": "^3.5.40",
79
- "@tmagic/core": "1.8.0-beta.17"
79
+ "@tmagic/core": "1.8.0-beta.18"
80
80
  },
81
81
  "peerDependenciesMeta": {
82
82
  "typescript": {
@@ -19,14 +19,14 @@
19
19
  }
20
20
  .el-card__body {
21
21
  .tmagic-design-form-item {
22
- margin-bottom: 18px;
22
+ margin-bottom: 16px;
23
23
  }
24
24
  }
25
25
  .code-select-content {
26
26
  > .m-fields-group-list {
27
27
  > .tmagic-design-card--flat {
28
28
  > .el-card__header {
29
- padding: 8px 0;
29
+ padding: 16px 0;
30
30
  }
31
31
  }
32
32
  }
@@ -34,7 +34,7 @@
34
34
  .create-button {
35
35
  &.fullWidth {
36
36
  width: 100%;
37
- margin: 0 0 8px 0;
37
+ margin: 0 0 16px 0;
38
38
  }
39
39
  }
40
40
  }
@@ -1,11 +1,14 @@
1
1
  .m-fields-event-select {
2
2
  width: 100%;
3
3
  .fullWidth {
4
- width: calc(100% - 32px);
4
+ width: 100%;
5
5
  box-sizing: border-box;
6
6
  &.create-button {
7
7
  width: 100%;
8
8
  }
9
+ &.m-container-ui-event {
10
+ width: calc(100% - 32px);
11
+ }
9
12
  }
10
13
  .event-select-container {
11
14
  padding: 0 16px;
@@ -14,7 +17,7 @@
14
17
  border-bottom: 1px solid #ebeef5;
15
18
  }
16
19
  > .el-card__body {
17
- padding-bottom: 8px;
20
+ padding-bottom: 16px;
18
21
  .m-fields-group-list-footer {
19
22
  div {
20
23
  justify-content: flex-start !important;
@@ -22,7 +25,7 @@
22
25
  }
23
26
  .el-card.tmagic-design-card--flat {
24
27
  > .el-card__header {
25
- padding: 8px 0;
28
+ padding: 16px 0;
26
29
  }
27
30
  }
28
31
  }
@@ -1,5 +1,7 @@
1
1
  import { EventEmitter } from 'events';
2
2
 
3
+ import { error } from '../logger';
4
+
3
5
  export interface IdleTaskEvents {
4
6
  finish: [];
5
7
  'hight-level-finish': [];
@@ -64,7 +66,7 @@ export class IdleTask<T = any> extends EventEmitter {
64
66
  this.taskHandle = null;
65
67
 
66
68
  this.emit('update-task-length', {
67
- length: this.taskList.length + this.hightLevelTaskList.length,
69
+ length: this.getTaskLength(),
68
70
  hightLevelLength: this.hightLevelTaskList.length,
69
71
  });
70
72
  }
@@ -88,51 +90,80 @@ export class IdleTask<T = any> extends EventEmitter {
88
90
  }
89
91
 
90
92
  private runTaskQueue(deadline: IdleDeadline) {
91
- const { hightLevelTaskList, taskList } = this;
92
-
93
- // 动画会占用空闲时间,当任务一直无法执行时,看看是否有动画正在播放
94
- // 根据空闲时间的多少来决定执行的任务数,保证页面不卡死的情况下尽量多执行任务,不然当任务数巨大时,执行时间会很久
95
- // 执行不完不会影响配置,但是会影响画布渲染
96
- while (deadline.timeRemaining() > 0 && (taskList.length || hightLevelTaskList.length)) {
97
- const timeRemaining = deadline.timeRemaining();
98
- let times = 0;
99
- if (timeRemaining <= 5) {
100
- times = 10;
101
- } else if (timeRemaining <= 10) {
102
- times = 100;
103
- } else if (timeRemaining <= 15) {
104
- times = 300;
105
- } else {
106
- times = 600;
107
- }
93
+ // 本次回调已触发,句柄随之失效;置空后 clearTasks / enqueueTask 才能正确判断是否需要重新调度
94
+ this.taskHandle = null;
108
95
 
109
- for (let i = 0; i < times; i++) {
110
- const task = hightLevelTaskList.length > 0 ? hightLevelTaskList.shift() : taskList.shift();
111
- if (task) {
112
- task.handler(task.data);
96
+ try {
97
+ // 动画会占用空闲时间,当任务一直无法执行时,看看是否有动画正在播放
98
+ // 根据空闲时间的多少来决定执行的任务数,保证页面不卡死的情况下尽量多执行任务,不然当任务数巨大时,执行时间会很久
99
+ // 执行不完不会影响配置,但是会影响画布渲染
100
+ while (deadline.timeRemaining() > 0 && this.getTaskLength()) {
101
+ const timeRemaining = deadline.timeRemaining();
102
+ let times = 0;
103
+ if (timeRemaining <= 5) {
104
+ times = 10;
105
+ } else if (timeRemaining <= 10) {
106
+ times = 100;
107
+ } else if (timeRemaining <= 15) {
108
+ times = 300;
109
+ } else {
110
+ times = 600;
113
111
  }
114
112
 
115
- if (hightLevelTaskList.length === 0 && taskList.length === 0) {
116
- break;
113
+ for (let i = 0; i < times; i++) {
114
+ // 每次都从实例上取队列,任务执行过程中调用 clearTasks 能立即生效,不会继续消费已被清空的旧队列
115
+ const task = this.hightLevelTaskList.length > 0 ? this.hightLevelTaskList.shift() : this.taskList.shift();
116
+ if (task) {
117
+ this.runTask(task);
118
+ }
119
+
120
+ if (!this.getTaskLength()) {
121
+ break;
122
+ }
117
123
  }
118
124
  }
125
+ } finally {
126
+ // 必须放在 finally 中:一旦这里被跳过,taskHandle 会一直是真值,
127
+ // enqueueTask 也就不会再重新调度,剩余任务与任务数将永久停在当前状态
128
+ this.finishRun();
119
129
  }
130
+ }
120
131
 
121
- if (!hightLevelTaskList.length) {
122
- this.emit('hight-level-finish');
132
+ /**
133
+ * 单个任务失败不能中断整个队列,否则后续任务永远不会被执行,
134
+ * 依赖收集会停在半路(收集中状态与剩余任务数都不再变化)
135
+ */
136
+ private runTask(task: TaskList<T>[number]) {
137
+ try {
138
+ task.handler(task.data);
139
+ } catch (e) {
140
+ error('magic editor: 空闲任务执行失败', e);
123
141
  }
142
+ }
124
143
 
125
- if (hightLevelTaskList.length || taskList.length) {
126
- this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
127
- } else {
128
- this.taskHandle = 0;
144
+ private finishRun() {
145
+ try {
146
+ if (!this.hightLevelTaskList.length) {
147
+ this.emit('hight-level-finish');
148
+ }
149
+ } finally {
150
+ if (this.getTaskLength()) {
151
+ // 任务执行或事件监听中可能已经重新调度过
152
+ if (!this.taskHandle) {
153
+ this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
154
+ }
155
+ } else {
156
+ this.emit('finish');
157
+ }
129
158
 
130
- this.emit('finish');
159
+ this.emit('update-task-length', {
160
+ length: this.getTaskLength(),
161
+ hightLevelLength: this.hightLevelTaskList.length,
162
+ });
131
163
  }
164
+ }
132
165
 
133
- this.emit('update-task-length', {
134
- length: taskList.length + hightLevelTaskList.length,
135
- hightLevelLength: hightLevelTaskList.length,
136
- });
166
+ private getTaskLength() {
167
+ return this.taskList.length + this.hightLevelTaskList.length;
137
168
  }
138
169
  }
package/types/index.d.ts CHANGED
@@ -3373,6 +3373,13 @@ declare class IdleTask<T = any> extends EventEmitter {
3373
3373
  once<Name extends keyof IdleTaskEvents, Param extends IdleTaskEvents[Name]>(eventName: Name, listener: (...args: Param) => void | Promise<void>): this;
3374
3374
  emit<Name extends keyof IdleTaskEvents, Param extends IdleTaskEvents[Name]>(eventName: Name, ...args: Param): boolean;
3375
3375
  private runTaskQueue;
3376
+ /**
3377
+ * 单个任务失败不能中断整个队列,否则后续任务永远不会被执行,
3378
+ * 依赖收集会停在半路(收集中状态与剩余任务数都不再变化)
3379
+ */
3380
+ private runTask;
3381
+ private finishRun;
3382
+ private getTaskLength;
3376
3383
  }
3377
3384
  //#endregion
3378
3385
  //#region temp/packages/editor/src/utils/scroll-viewer.d.ts