vue的异步更新机制,学习vue源码的总结

  • vue的双向绑定基于Object.defineProperty以及对于数组原型改变数组自身的7种方法进行增强来实现。
  • 在其值发生改变时,通过拦截数据时设置的dep实例调用dep.notify()即循环dep实例的subs数组(一个由wacher所组成的数组),调用每个watcher的update方法
  • update将会分作三种情况执行,此处对于lazy为真情况(即computed)以及sync为真(同步直接执行watcher的run进行更新)不做深究
  • 在一般情况下,update实际是调用了queueWatcher函数将watcher加入全局的queue数组,通过执行nextTick方法,其回调函数为flushSchedulerQueue(将queue数组进行排序,排序原因源码有注释,并执行watcher的run方法)
  • nextTick:将每个flushSchedulerQueue放入全局的callbacks,若此时浏览器的异步任务队列中没有一个叫 flushCallbacks 的函数,则执行 timerFunc 函数,将 flushCallbacks 函数放入异步任务队列。如果异步任务队列中已经存在 flushCallbacks 函数,等待其执行完成以后再放入下一个 flushCallbacks 函数 注意flushCallbacks 是在timerFunc(异步函数)里执行的。 Vue.nextTick也是此方法
  • timerFunc:将任务加入异步队列,通过Promise,MutationObserver,setImmediate,setTimeout的优先级进行浏览器兼容处理
  • flushCallbacks :依次执行callbacks数组中的方法
  • 所以以上简单言之其实就是在异步执行watcher的run方法
if (!flushing) {
      queue.push(watcher)
    } else {
      // 如何出现异步更新已经执行 还有执行queueWatcher的情况
      // if already flushing, splice the watcher based on its id       如果已经是flushing状态则将其加入queue  
      // if already past its id, it will be run next immediately.   如果已经过了它的id,它将被立即运行
      let i = queue.length - 1
      while (i > index && queue[i].id > watcher.id) {
        i--
      }
      queue.splice(i + 1, 0, watcher)
    }

这部分代码始终理解不了,如何出现异步更新已经执行 还有执行queueWatcher的情况,queueWatcher始终是在同步执行,vue也始终是用最快的异步来进行异步更新,是基于未来可能存在的新的异步方案考虑?
如果是一个用户 watcher,即 watch 选项,监听到数据更新,经过异步更新队列的过程,最后开始刷新队列,执行 watcher.run -> watcher.get -> 最后执行 watch 选项的回调函数,如果回调函数中有更新另一个响应式数据的情况,这时候就会触发 setter,然后触发依赖通知更新,接着 watcher 入队。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值