先解释一下什么是迭代计算(循环引用):
例如,在Sheet1 中,A1引用了B1,B1又引用了A1,或者A1直接引用A1,这样直接或间接的“自己引用自己”的现象,就是迭代计算(又称循环引用)。
那么,当遇到这个情况时,Excel是怎么处理的呢?
默认情况下,Excel会弹出提示窗,告知使用者,可能出现了循环引用的问题,导致计算结果不正确(大概率会无限计算下去,而不会得到正确的结果),针对这种现象,Excel提供了配置项,可以用来配置迭代计算的最大深度和最大误差(误差会在迭代计算过程中积累),如图所示:
(感谢某SpreadJS资深使用团队提供的反馈)
SpreadJS针对这个场景,又是如何处理的呢?
众所周知,由于JavaScript是单线程运行的,因此,不可能像Excel那样,让迭代计算的公式无限深度地计算下去,这样一定会导致页面崩溃。
在V13以及更早版本中,当SpreadJS遇到这种情况,默认会在计算执行到一定深度后跳出计算,就像上图中Excel中配置的那样,以避免阻塞页面的响应并且能够继续正常执行后边的步骤,并得到最终的结果。
但是如果深究起来,这种方案实际上是有潜在问题的:这与Excel中默认行为不一致。当我们向SpreadJS导入一个包含迭代计算的Excel文档时,相同的逻辑得到了不同的计算结果,这在一些应用场景中是无法忍受的。
因此,在V14版本中,我们统一了SpreadJS与Excel的行为,支持了包括阻断计算逻辑、提供提醒事件、提供了可配置项的特性。下边我一一介绍:
1、阻断计算逻辑:当产生循环引用时,为了不阻塞页面,SpreadJS会停止计算引擎,这会导致公式不会再得到正确的结果;
2、提供提醒事件:计算引擎停止计算后,必须要有通知机制。SpreadJS提供了新的事件来响应,详情见学习指南;
3、提供了可配置项:与Excel一样,SpreadJS也提供了最大深度、最大误差的配置属性,详情见学习指南;
学习指南:迭代计算
潜在问题:
以上详细解释了迭代计算的产生原因、平台局限性、新旧版本的差异。那么这就给从旧版SpreadJS升级到V14版本的用户带来一个潜在的问题:当遇到迭代计算的场景时,默认行为不一致了。以前依赖于SpreadJS底层静默处理的场景,现在需要做一些特殊处理,否则会导致计算结果不一致(新旧版本不一致,但V14新版SpreadJS计算行为和结果与Excel一致了)。
所以提醒有潜在风险的小伙伴,请参考学习指南,根据自己的业务需求,提前做好配置。
|
|