Vue.js---立即执行的watch与回调执行时机

4.8 立即执行的watch与回调执行时机

1、立即执行的watch

watch 的两个特性:一个是立即执行的回调函数,另一个是回调函数的执行时机。

立即执行的回调函数:

// 回调函数只有在响应式数据 obj 后续发生变化时才执行 
 watch(obj, () => { 
   console.log('变化了') 
    // 回调函数会在 watch 创建时立即执行一次 
   immediate: true 
 })

现在我们就要来完成这个功能:当 immediate 选项存在并且为 true 时,回调函数会在该watch 创建时立刻执行一次。所以我们可以把 scheduler 调度函数封装为一个通用函数,分别在初始化和变更时执行它。

    // watch函数:传入参数source以及回调函数
    function watch(source , cb) {
      // 定义job,就是把scheduler的内容进行提取
      const job = () => {
        // 值发生改变会发生,此时就有新值了
            newVal = effectFn()
            // 回调函数,传入新旧值
            cb(oldVal , newVal)
            // 一定要记得更新旧值
            oldVal = newVal
      }
      // 定义getter
      let getter 
      if(typeof source === 'function'){
        getter = source
      }else {
        getter = () => traverse(source)
      }
      // 定义新旧值
      let newVal , oldVal
      const effectFn = effect(
        () => getter(),
        {
          lazy: true,
          scheduler:job //改变的时候执行job
        }
      )
      // 判断是否有immediate,有immediate就在最开始就要执行job
      if(options.immediate){
        // 执行job
        job();
      }else {
        oldVal = effectFn();
      }
      // 调用effectFn就是旧值
      oldVal = effectFn();
    }

2、回调执行的时机

watch中flush 本质上是在指定调度函数的执行时机。当 flush 的值为 ‘post’ 时,代表调度函数需要将副作用函数放到一个微任务队列中,并等待 DOM 更新结束后再执行

   // watch函数:传入参数source以及回调函数
    function watch(source , cb) {
      // 定义job,就是把scheduler的内容进行提取
      const job = () => {
        // 值发生改变会发生,此时就有新值了
            newVal = effectFn()
            // 回调函数,传入新旧值
            cb(oldVal , newVal)
            // 一定要记得更新旧值
            oldVal = newVal
      }
      // 定义getter
      let getter 
      if(typeof source === 'function'){
        getter = source
      }else {
        getter = () => traverse(source)
      }
      // 定义新旧值
      let newVal , oldVal
      const effectFn = effect(
        () => getter(),
        {
          lazy: true,
          scheduler:() => {
            if(options.flush === 'post'){
              const p = Promise.resolve();
              p.then(job);
            }else {
              job()
            }
          }
        }
      )
      // 判断是否有immediate
      if(options.immediate){
        // 执行job
        job();
      }else {
        oldVal = effectFn();
      }
      // 调用effectFn就是旧值
      oldVal = effectFn();
    }

在调度器函数内检测 options.flush 的值是否为 post,如果是,则将 job 函数放到微任务队列中,从而实现异步延迟执行;否则直接执行 job 函数,这本质上相当于 ‘sync’ 的实现机制,即同步执行。
之后很长一段时间我就不会看vue.js这本书啦,我的学长说现在市面上很多公司都改为react啦,react更加灵活,我之后会分享更多react的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值