Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,10 @@ export class FormStore {
}
}

this.notifyWatch([namePath]);
// Avoid exponential loops when a large number of components are unloaded
setTimeout(() => {
this.notifyWatch([namePath]);
})
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

延迟方式仍存 O(N²) 隐患,建议合并为单次去抖触发

当前实现在每个 Field 卸载时都 setTimeout 一次,notifyWatch 仍会被调用 n 次;notifyWatch → getFieldsValue 会遍历全部剩余字段,整体复杂度依旧可能退化为 O(n²)。可以考虑为整个卸载阶段只触发一次异步通知,例如增加一个“待刷”标记并在下一个宏/微任务中统一执行:

+// 顶部成员
+private pendingNotify: boolean = false;

@@
-      // Avoid exponential loops when a large number of components are unloaded
-      setTimeout(() => {
-        this.notifyWatch([namePath]);
-      })
+      // 避免多次重复调用,统一去抖
+      if (!this.pendingNotify) {
+        this.pendingNotify = true;
+        Promise.resolve().then(() => {
+          this.pendingNotify = false;
+          this.notifyWatch();      // 合并调用,不再逐个 namePath
+        });
+      }

这样无论一次批量卸载多少 Field,只会有一次 notifyWatch 调用,可彻底消除指数级循环风险。
[建议级别: 必需优化]

🤖 Prompt for AI Agents
In src/useForm.ts around lines 685 to 689, the current implementation calls
setTimeout for each Field unload, causing notifyWatch to be invoked multiple
times and leading to O(n²) complexity. To fix this, implement a debounce
mechanism by adding a flag to mark pending notifications and schedule a single
notifyWatch call in the next macro or microtask, ensuring that no matter how
many Fields unload in a batch, notifyWatch is only called once, eliminating the
exponential loop risk.

};

Expand Down