Vue2剥丝抽茧-响应式系统之异步队列
Vue2 源码从零详解系列文章,剥步队 还没有看过的丝抽同学可能需要看一下之前的,vue.windliang.wang。茧响
场景import { observe } from "./reactive";
import Watcher from "./watcher";
const data = {
a: 1,应式
b: 2,
c: 3,
};
observe(data);
const updateComponent = () => {
console.log(data.a + data.b);
};
new Watcher(updateComponent);
const updateComponent2 = () => {
console.log(data.c);
};
new Watcher(updateComponent2);
data.a = 2;
data.a = 3;
data.b = 4;
data.c = 5;new Watcher(updateComponent) 进行依赖收集会输出一次 3 ,new Watcher(updateComponent2) 进行依赖收集也会输出一次 3 。系统
之后我们依次改变 a、剥步队 a 、丝抽b、茧响c 的应式值,每改变一次就会触发 Watcher 的源码下载系统执行,会连续进行四次的剥步队 console.log。
试想一下如果这里的丝抽 console.log 是渲染页面,那改变一次值就刷新一下页面,茧响会造成严重的应式性能问题,页面也会不停的系统改变。
解决方案我们可以通过一个队列,服务器租用收集所有的 Watcher 。
那什么时候执行 Watcher 队列呢?
为了等所有的 Watcher 都收集完毕,可以将 Watcher 的执行放到 setTimeout 中。这样当主线程全部执行后,才会去执行 Watcher 队列。
代码实现我们可以给每一个 Watcher 加上一个 id,如果队列中已经有 id 了就不加入队列。
let uid = 0;
export default class Watcher {
constructor(Fn, options) {
this.getter = Fn;
this.depIds = new Set(); // 拥有 has 函数可以判断是否存在某个 id
this.deps = [];
this.newDeps = []; // 记录新一次的源码库依赖
this.newDepIds = new Set();
/