it("scheduler", () => {
// 1. 通过 effect 的第二个参数给定一个 scheduler 的 fn
// 2. effect 第一次执行的时候 还会执行 fn
// 3. 当响应式对象 set update 不会执行 fn 而是执行 scheduler
// 4. 如果说当执行 runner 的时候,会再次执行 fn
let dummy;
let run: any
const scheduler = jest.fn(() => {
run = runner
})
const obj = reactive({foo: 1})
const runner = effect(() => {
dummy = obj.foo
}, {
scheduler
})
expect(scheduler).not.toHaveBeenCalled()
expect(dummy).toBe(1)
obj.foo++
expect(scheduler).toHaveBeenCalledTimes(1)
expect(dummy).toBe(1)
run()
expect(dummy).toBe(2)
})
class ReactiveEffect {
private _fn: any;
+ scheduler: any;
+ constructor(fn, scheduler?: any) {
this._fn = fn
+ this.scheduler = scheduler
}
run() {
// 把实例对象赋值给 activeEffect
activeEffect = this
return this._fn()
}
}
export function trigger(target,key) {
let depsMap = targetMap.get(target)
let dep = depsMap.get(key)
for (const effect of dep) {
+ if (effect.scheduler) {
+ effect.scheduler()
+ } else {
+ effect.run()
+ }
}
}
export function effect(fn, options: any = {}) {
+ const _effect = new ReactiveEffect(fn, options.scheduler)
_effect.run()
return _effect.run.bind(_effect)
}