编辑
scheduler
scheduler(调度),我们函数的执行需要调度控制,它就相当于一个开关,来把控是否要执行fn,当我们传入了scheduler时,就不会去执行fn了,我们先来写个单元测试,来把理想的功能写一下
编辑
这里当我们obj.foo++时会触发effect函数执行,但是我们传入了scheduler,所以fn不会再走了,而是去执行scheduler ,因此dummy = obj.foo这里的逻辑走不了,所以dummy的值不会更新
我们来改动一下effect, 这里为什么要用Object.assign()为依赖项绑定options呢,因为我们再执行依赖性的时候要根据options上的属性来控制,所以当trigger时,我们会检查一下options选项,所以要给_effect绑
复制代码
export function effect(fn, options: any = {}) { const _effect = new reactiveEffect(fn, options.schdeuler) // extend(_effect, options) Object.assign(_effect, options) _effect.run() const runner: any = _effect.run.bind(_effect) runner._effect = _effect return runner }
class reactiveEffect { private _fn: any //用于将那个依赖存进去 deps = [] active = true constructor(fn, public schduler?: Function) { this._fn = fn this.schduler = schduler } run() { activeEffect = this return this._fn() } stop() { if (this.active) { this.active = false //这里存放的dep是set结构,所以需要delete来操作 clearEffect(this) } } }
export function trigger(target, key) { const depMap = targetMap.get(target) const deps = depMap.get(key) for (const dep of deps) { if (dep.scheduler) { dep.scheduler() } else { dep.run() } } }
这样当我们有scheduler时,在依赖触发时就会调用scheduler而不是fn了,所以就实现了控制fn的调用
onStop
onStop是stop之后的回调函数,stop上节我们有讲到过, 调用stop之后我们依赖性会被清空,同时也不会再收集依赖, 这样就监听不了reactive对象的变化了,onStop也就是stop之后的回调,因此我们在stop函数中调用即可
class reactiveEffect { private _fn: any //用于将那个依赖存进去 deps = [] active = true onStop?: () => void constructor(fn, public schduler?: Function) { this._fn = fn this.schduler = schduler } run() { activeEffect = this return this._fn() } stop() { if (this.active) { this.active = false //这里存放的dep是set结构,所以需要delete来操作 clearEffect(this) if (this.onStop) { this.onStop() } } } }
到此就已经实现了scheduler以及onStop的功能了
写在最后
options其实还有很多配置项,这里挑最核心的内容来复现,直接看本篇章可能有些吃力,希望这次的博客工程能像连续剧一样让大家看得津津有味。