手撸vue3核心源码——响应式原理(scheduler以及onStop)

在我们给effect函数传入fn函数的同时也可以传入一些配置项,这里拿scheduler以及onStop来举个例子

 

scheduler

scheduler(调度),我们函数的执行需要调度控制,它就相当于一个开关,来把控是否要执行fn,当我们传入了scheduler时,就不会去执行fn了,我们先来写个单元测试,来把理想的功能写一下

这里当我们obj.foo++时会触发effect函数执行,但是我们传入了scheduler,所以fn不会再走了,而是去执行scheduler ,因此dummy = obj.foo这里的逻辑走不了,所以dummy的值不会更新

我们来改动一下effect, 这里为什么要用Object.assign()为依赖项绑定options呢,因为我们再执行依赖性的时候要根据options上的属性来控制,所以当trigger时,我们会检查一下options选项,所以要给_effect绑定好options

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其实还有很多配置项,这里挑最核心的内容来复现,直接看本篇章可能有些吃力,希望这次的博客工程能像连续剧一样让大家看得津津有味。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值