【发布时间】:2021-12-30 22:01:09
【问题描述】:
假设您有一个计算属性,它根据用户的输入过滤和排序一组值。
如果用户开始从数组中过滤值,并且在过滤的计算过程中排序值发生变化,计算属性是继续执行过滤,还是计算属性跳转到计算属性的下一个计算在队列中,使用新的排序值?
【问题讨论】:
标签: javascript vue.js frontend reactive-programming
假设您有一个计算属性,它根据用户的输入过滤和排序一组值。
如果用户开始从数组中过滤值,并且在过滤的计算过程中排序值发生变化,计算属性是继续执行过滤,还是计算属性跳转到计算属性的下一个计算在队列中,使用新的排序值?
【问题讨论】:
标签: javascript vue.js frontend reactive-programming
Javascript(本质上)是单线程的。这意味着在当前正在执行的同步代码完成执行之前,甚至无法处理用户触发事件发生的事实。
不过,您可以自己做一些事情来模仿这一点。在释放允许处理事件的运行循环的地方添加异步暂停,然后恢复并检查一些取消条件,然后您可能能够实现您所要求的事情。但这是很多代码,除非过滤真的很慢,否则这可能是个坏主意。
【讨论】:
计算属性将完全执行完毕。
如果old Vue.js v2 documentation 仍然具有任何相关性,则以下段落表明更改如何导致更新:
[...]Vue 异步执行 DOM 更新。每当观察到数据更改时,它将打开一个队列并缓冲在同一事件循环中发生的所有数据更改。如果同一个 watcher 被多次触发,它只会被推入队列一次。这种缓冲的重复数据删除对于避免不必要的计算和 DOM 操作很重要。然后,在下一个事件循环“tick”中,Vue 刷新队列并执行实际的(已经去重复的)工作。
鉴于 JavaScript 是一种单线程语言,这意味着在事件循环的任何特定“tick”期间,在此“tick”期间的代码执行完成之前,不会处理其他操作。
如果假设 Vue 的内部行为是纯粹异步处理这些更新,那么任何两个事件循环滴答之间都可能出现竞争条件,特别是如果第一个滴答需要很长时间才能完成而第二个滴答完成迅速地。中途停止计算属性的执行,即使可能,也可能导致通常由计算属性的执行触发的任何副作用(不好的做法,但这是另一个主题)不会被触发。
这些行为上的不一致会导致应用程序状态保持一致性的各种问题,这个问题会使任何反应式框架实际上毫无价值。
【讨论】: