单测
//effect.spec.tsit('scheduler', () => { // 1. scheduler 作为 effect 的一个 option // 2. 有了 scheduler 之后原来的 fn 参数只会执行初始化的一次 // 3. 如果依赖更新时不会执行 fn ,而是会去执行 scheduler // 4. runner 不受影响 let dummy let run: any const scheduler = jest.fn(() => { run = runner }) const obj = reactive({ foo: 1 }) // 在这里将 scheduler 作为一个 option 传入 effect const runner = effect( () => { dummy = obj.foo }, { scheduler } ) expect(scheduler).not.toHaveBeenCalled() // 会执行一次 effect 传入的 fn expect(dummy).toBe(1) obj.foo++ // 有了 scheduler 之后,原来的 fn 就不会执行了 expect(scheduler).toHaveBeenCalledTimes(1) expect(dummy).toBe(1) run() expect(dummy).toBe(2) })
//effect.tsclass ReactiveEffect{ private _fn constructor(fn,public scheduler?){ this._fn = fn } run(){ activeEffect = this let res =this._fn() return res }}let activeEffectconst targetMap = new WeakMap()export function track(target, key){ let depsMap = targetMap.get(target) if(!depsMap){ depsMap = new Map() targetMap.set(target,depsMap) } let dep = depsMap.get(key) if(!dep){ dep = new Set() depsMap.set(key,dep) } dep.add(activeEffect)}export function trigger(target, key){ let depsMap = targetMap.get(target) let deps = depsMap.get(key) for(const effect of deps){ //在批改值的时候,有scheduler先执行scheduler if(effect.scheduler){ effect.scheduler() }else{ effect.run() } }}export function effect(fn,option:any={}){ //讲option.scheduler传入参数 const _effect = new ReactiveEffect(fn,option.scheduler) _effect.run() return _effect.run.bind(_effect) }