问题描述Vue中,如果wather不是同步更新的话,会放到一个队列中,同一事件循环结束后再更新。相关代码再scheduler的queueWatcher方法中。这里面处理一个场景:当这个队列正在更新时,又触发了wather。 if (!flushing) {
queue.push(watcher)
} else {
let i = queue.length - 1
while (i > index && queue[i].id > watcher.id) {
i--
}
queue.splice(i + 1, 0, watcher)
}
}不明白为什么要这么处理。直接push到最后不行吗?现在这样的设计又有什么好处?追加描述,vue这段代码也并不是同一个时间循环中,还没执行这个wather,再次触发这个wather就只执行一次。queue.splice(i + 1, 0, watcher)这边是知道这个wather之前的index,并把第二次触发放到这个后面。也还是执行两次update。既然都是执行两次,为什么不直接push到最后
1 回答
米脂
TA贡献1836条经验 获得超3个赞
自问自答一下。这个问题其实想说清楚也很简单。之所以要以队列缓存起来,就是为了避免不必要更新。如,
data: { a: 1}, computed: { b: function(){ this.a + 1 } } methods: { act: function(){ this.a = 2; // do someting this.a = 1 } }
在act操作中,我们先改变a,再把它变回来。我们理想状况下是a没变,b也不重新计算。其实想想就知道这是做不到的。因为只要a改变了b的wather就已经在更新队列中了。我们能避免的,只是b的改变已经的其他计算。
这就要求,b的wather执行update的时候要拿到a最新的值来计算。这里就是1。
回到问题中来,如果队列中a的watehr已经更新过,那么就应该把后面的a的wather放到当前更新的wather后面,立即更新。这样可以保证后面的wather用到a是可以拿到最新的值。
同理,如果a的wather还没有更新,那么把新的a的wather放的之前的a的wather的下一位,也是为了保证后面的wather用到a是可以拿到最新的值
添加回答
举报
0/150
提交
取消