scheduler的实现
scheduler是effect函数的第二个参数,schedule是一个函数
在测试中书写最核心的代码流程
it("scheduler",()=>{
//1.通过effect的第二个参数给定的scheduler的一个函数
//2.当effect第一次执行时还会执行effect的第一个参数(回调函数)
//3.当响应式对象触发set 值更新时,不会执行fn,而是执行scheduler
//4.如果说执行runner的时候,会再次执行fn(effect的第一个参数)
let dummy;
let run:any;
//scheduler接收一个函数
const scheduler=jest.fn(()=>{
run=runner;
});
const obj=reactive({foo:1});
const runner=effect(
()=>{
dummy=obj.foo;
},
{scheduler}
);
//断言scheduler一开始不会被调用
expect(scheduler).not.toHaveBeenCalled();
//判断dummy值是否为1,如果为1,说明effect的第一个函数会执行 第二个函数不会执行
expect(dummy).toBe(1);
//should be called on first trigger
//当响应式对象的值发生改变
obj.foo++;
//当响应式对象的值发生改变,会调用scheduler,而不会再次执行()=>{dummy=obj.foo;},
expect(scheduler).toHaveBeenCalledTimes(1);
//should not run yet
//dummy值仍然为1,说明没有执行()=>{dummy=obj.foo;},
expect(dummy).toBe(1);
//manually run
run();
//should have run
expect(dummy).toBe(2);
});
那么具体如何实现呢?
首先要在effect函数中接收第二个参数options,在effect里面获取到scheduler
然后scheduler一开始不会被调用,当响应式对象的值发生改变,会调用scheduler,而不会再次执行()=>{dummy=obj.foo;},由于当响应式对象的值发生改变会触发trigger函数,trigger里面会调用run方法来执行收集的依赖,即运行effect的第一个函数,因此可以在这里判断一下
如何把scheduler传进去
scheduler功能完成,完整代码见下篇文章