美文网首页
effect 的 stop

effect 的 stop

作者: sweetBoy_9126 | 来源:发表于2024-03-16 13:58 被阅读0次
    1. stop
    • effect.spec.ts
      核心调用 stop 的时候把对应的dep里的fn 删掉
      it("stop", () => {
        let dummy
        const obj = reactive({prop: 1})
        const runner = effect(() => {
          dummy = obj.prop
        })
        obj.prop = 2
        expect(dummy).toBe(2)
        stop(runner)
        obj.prop = 3
        expect(dummy).toBe(2)
        runner()
        expect(dummy).toBe(3)
      })
    
    • effect.ts
    class ReactiveEffect {
      ...
    +  deps: any = []
    +  stop() {
    +    this.deps.forEach(dep => {
    +     dep.delete(this)
    +   }) 
    +  }
    }
    export function track(target, key) {
      ...
    +  activeEffect.deps.push(dep)  
    }
    export function effect(fn, options: any = {}) {
      const _effect = new ReactiveEffect(fn, options.scheduler)
     _effect.run()
     const runner: any = _effect.run.bind(_effect)
    + runner.effect = _effect
     return runner
    }
    +export function stop(runner) {
    +  runner.effect.stop()
    +}
    
    1. onStop
    • effect.sepc.ts
      it("onStop", () => {
        const obj = reactive({
          foo: 1
        })
        const onStop = jest.fn()
        let dummy
        const runner = effect(() => {
          dummy = obj.foo
        }, {
          onStop
        })
        stop(runner)
        expect(onStop).toBeCalledTimes(1)
      })
    
    • effect.ts
    class ReactiveEffect {
      
      onStop?: () => void
      stop() {
        if (this.active) {
          cleanupEffect(this)
          if (this.onStop) {
            this.onStop()
          }
          this.active = false
        }
      }
    }
    export function effect(fn, options: any = {}) {
      const _effect: any = new ReactiveEffect(fn, options.scheduler)
      _effect.onStop = options.onStop
      ...
    }
    
    1. 优化
      之前的代码里
      it("stop", () => {
        let dummy
        const obj = reactive({prop: 1})
        const runner = effect(() => {
          dummy = obj.prop
        })
        obj.prop = 2
        expect(dummy).toBe(2)
        stop(runner)
        // obj.prop = 3
        obj.prop++
        expect(dummy).toBe(2)
        runner()
        expect(dummy).toBe(3)
      })
    

    我如果把 obj.prop = 3换成 obj.prop++ 的话单测就会报错

    原因:
    obj.prop = 3 是直接 set

    obj.prop++ 实际上就是 obj.prop = obj.prop + 1 既有 get 又有 set,而触发 get 又重新收集了依赖

    let shouldTrack
    export function track(target, key) {
      ...
      if(!activeEffect) return
    +  if (!shouldTrack) return
      ...
    }
    
      run() {
        // 是 stop
    +    if (!this.active) {
    +      return this._fn()
    +    }
        // 不是 stop
    +    shouldTrack = true
        // 把实例对象赋值给 activeEffect
    +    activeEffect = this
    +    const result = this._fn()
    +    shouldTrack = false
    +    return result
      }
    

    相关文章

      网友评论

          本文标题:effect 的 stop

          本文链接:https://www.haomeiwen.com/subject/jpetmdtx.html