单测
//effect.spec.ts
it('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.ts
class ReactiveEffect{
private _fn
constructor(fn,public scheduler?){
this._fn = fn
}
run(){
activeEffect = this
let res =this._fn()
return res
}
}
let activeEffect
const 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)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。