arrayInstrumentations速览(3)

arrayInstrumentations主要是改写数组的方法
1.改写includes、indexOf、lastIndexOf这三个方法。这三个方法无法'准确'追踪数组中元素。具体表现如下(案例来自网络)

       const arr = reactive([2,1,3])
       effect(() => {
         console.log(arr.indexOf(2))
       })
       setTimeout(() =>{
         arr[1] = 4
       }, 5000)

当修改arr[1]的值时,将会触发副作用函数的的执行,但arr[1]值的改变并不会影响副作用函数的结果(arr[0]不等于2时才影响),因此可以判定是无效的触发。
因此当调用的是这三个方法时,要对数组中的每个元素进行依赖收集,这样才能正确触发,这里还要注意处理参数已经被proxy代理的情况

;(['includes', 'indexOf', 'lastIndexOf'] as const).forEach(key => {
    instrumentations[key] = function (this: unknown[], ...args: unknown[]) {
      const arr = toRaw(this) as any
      for (let i = 0, l = this.length; i < l; i++) {
        track(arr, TrackOpTypes.GET, i + '')
      }
      // we run the method using the original args first (which may be reactive)
      const res = arr[key](...args)
      if (res === -1 || res === false) {
        // if that didn't work, run it again using raw values.
        return arr[key](...args.map(toRaw))
      } else {
        return res
      }
    }
  })

2.改写push、pop、shift、unshift、splice这三个方法。这三个方法是直接调用数组对应的方法,返回对应的结果,不进行额外的依赖收集

// instrument length-altering mutation methods to avoid length being tracked
// which leads to infinite loops in some cases (#2137)
  ;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => {
    instrumentations[key] = function (this: unknown[], ...args: unknown[]) {
      pauseTracking()
      const res = (toRaw(this) as any)[key].apply(this, args)
      resetTracking()
      return res
    }
  })
export function pauseTracking() {
  trackStack.push(shouldTrack)
  shouldTrack = false
}
export function resetTracking() {
  const last = trackStack.pop()
  shouldTrack = last === undefined ? true : last
}

为什么这么做呢?从注释中找到的信息是避免length改变陷入无尽的回调。那么如果此处不进行依赖收集,那么依赖收集是在哪一块进行的呢?让我们回看上一章中mutableHandlers方法,此方法只是针对数组这八个方法进行改写,那么length属性呢,不在这当中,还是继续往下执行,会进行依赖收集。因此如果这里再进行依赖收集,那么就会重复,因此不需要再进行收集。

下文主要对依赖收集函数track进行展开!
本人菜鸡,有问题望前辈及时指出,不胜感激!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容