Skip to content

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

@Manwzy

Description

@Manwzy
  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

Edit on CodeSandbox

Steps to reproduce

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

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 标记位——如果检测到当前已在清空过程中,则直接退出,避免冗余嵌套调用?

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]


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions