【探究Vue原理】watcher的异步更新

本文详细探讨Vue中watcher的异步更新原理,包括同步更新与异步更新的区别。重点分析Vue如何通过flushSchedulerQueue和queueWatcher管理更新队列,确保DOM更新的高效性和顺序性,并避免重复更新。通过源码解读,揭示Vue处理边界情况的策略。
摘要由CSDN通过智能技术生成

 
 

开篇

  之前的文章提到过,当用户修改了组件状态之后,dep会通知它所关联的watcher进行更新。更新过程分两种,一种是同步更新,另一种是异步更新。

 
 

同步更新

  如果一个watcher实例的sync属性被置为true,则表明此watcher是同步更新的。同步更新的原理很简单,就是当dep通知某个watcher实例需要更新的时候,这个watcher实例直接调用callback方法进行更新。但在官网文档中甚至没有告诉用户options参数包含sync配置项。因此在我理解中,用户是无法创建同步更新的watcher的。
 
 

异步更新

  本文的重头戏来了。Vue中,所有的DOM更新都是异步更新,这是因为DOM更新是renderWatcher的callbak来调用的,而renderWacther是一个异步更新watcher。
  每当用户修改了组件状态,dep都会通知相关watcher,而这些watcher会调用名为queueWatcher的方法将自己放进更新队列。这里所谓的更新队列是一个由watcher组成的数组,Vue会在更新循环中遍历这个数组并依次调用其中每个watcher的callback。不过这里要注意:在一个更新循环内,同一个watcher在一般情况下只会被push到更新队列中一次。Vue使用异步更新的目的就是去除重复的DOM更新,比如下面这个代码:

 methods: {
   
    setName() {
   
      this.myName="a";
      this.myName="b";
      this.myName="c";
    }}

实际上,在一般情况下renderWatch只会执行一次,最终myName的值为c。

  我不断的提示一般情况下是因为Vue的异步更新逻辑远远没文档中描述的这么简单,实际上Vue处理了很多边界情况。下面贴上Vue源码,我们一点点分析。

 
 

异步更新的源码分析

源码位于 src\core\observer\scheduler.js文件中,其中最重要的两个函数为flushSchedulerQueuequeueWatcher。除此之外,每个watcher都有一个唯一的id,而has数组被用来保存当前更新循环中全部的watcher.id。上文提到的更新队列指的是源码中的queue数组。

flushSchedulerQueue

请结合下面的文章一起看。

function flushSchedulerQueue () {
   
  currentFlushTimestamp = getNow()
  flushing = true
  let watcher, id
  
  /* 以watcher.id对watcher进行有小到大排序 */
  queue.sort((a, b) => a.</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值