Skip to content

调度器 ​

本节目标:理解“调度器”的核心思路,并能把它用于实际开发或面试表达。

export class ReactiveEffect {
  public deps = [];
  public parent = null;
  public active = true
  constructor(public fn, ==public== ==scheduler==) { }
  run() {
    if (!this.active) {
      return this.fn();
    }
    try {
      this.parent = activeEffect;
      activeEffect = this;
      // 这里我们需要在执行用户函数之前将之前收集的内容清空
      cleanupEffect(this)
      return this.fn();
    } finally {
      activeEffect = this.parent;
      this.parent = null;
    }
  }
  ==stop====()== =={==
    ==if== ==(====this====.====active====)== =={==
      ==this====.====active== ===== ==false====;==
      ==cleanupEffect====(====this====);== ==//== ==停止====effect====的收集==
    ==}==
  ==}==
}
export const effect = (fn, options: any = {}) => {
  const _effect = new ReactiveEffect(fn, options.scheduler);
  _effect.run();
  // 将实例的Run方法绑定到effect上,然后作为返回值返回
  const runner = _effect.run.bind(_effect); // 绑定this执行
  // 将effect挂载到runner函数上
  runner.effect = _effect;
  return runner
}
export function trigger(target, type, key, value, oldValue) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return; // 触发的值不在模板中使用
  let effects = depsMap.get(key); // 找到了属性对应的effect
  // 永远在执行之前 先拷贝一份来执行, 不要关联引用
  if (effects) {
    triggerEffects(effects)
  }
}
export function triggerEffects(effects) {
  effects = new Set(effects);
  effects.forEach(effect => {
    // 我们在执行effect的时候,又要执行自己,那我们需要屏蔽掉,不要无限调用
    if (effect !== activeEffect) {
      if (effect.scheduler) {
        // 如果用户传入了调度函数,则用用户的
        effect.scheduler();
      } else {
        effect.run() // 否则默认刷新视图
      }
    }
  });
}
export function track(target, type, key) {
  if (!activeEffect) return;
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    targetMap.set(target, (depsMap = new Map()))
  }
  let dep = depsMap.get(key);
  if (!dep) {
    depsMap.set(key, (dep = new Set()))
  }
  trackEffects(dep);
}
export function trackEffects(dep) {
  if (activeEffect) {
    let shouldTrack = !dep.has(activeEffect); // 去重了
    if (shouldTrack) {
      dep.add(activeEffect);
      // 存放的是属性对应的set
      activeEffect.deps.push(dep);
    }
  }
}

本站总访问 — 次