#4306·formily

[Bug Report] Reaction数量多时,RangeError: Maximum call stack size exceeded

Author: ManwzyCreated Jun 4, 2025Updated Oct 13, 2025
  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

Edit on CodeSandbox

Steps to reproduce

打开后即可复现,复现代码如下

typescript
const data = observable({ count: 0 });
for(let i = 0;i < 1500; ++i){
  reaction(() => data.count, ()=>{
    console.log("Reaction:", data.count, i)
  })
}
data.count = 25

Image

What is expected?

reactions数量多时,也不会报错堆栈溢出

What is actually happening?

在清空PendingReactions堆栈过程中,由于reaction执行完成后,会再次进入batchEnd阶段,重新开始清空PendingReactions堆栈,导致整个调用链路是嵌套调用的,最终堆栈溢出。 实际上,一旦开始清空堆栈,就不需要重复触发清空流程?因此,可以在 batchDelete 方法中增加一个 isBatching 标记位——如果检测到当前已在清空过程中,则直接退出,避免冗余嵌套调用?

typescript
batchDelete(callback: (value: T) => void) {
    if (this.value.length === 0 || this.isBatching) return
    this.isBatching = true;
    this.forEachIndex = 0
    for (; this.forEachIndex < this.value.length; this.forEachIndex++) {
      const value = this.value[this.forEachIndex]
      this.value.splice(this.forEachIndex, 1)
      this.forEachIndex--
      callback(value)
    }
    this.isBatching = false;
  }

Package

@formily/[email protected]