首页 > 编程语言 >vue2源码-九、异步更新

vue2源码-九、异步更新

时间:2023-04-19 19:57:28浏览次数:43  
标签:timerFunc 异步 缓存 watcher 源码 let vue2 id

异步更新

  1. 异步更新原因

    以下情况下:

    vm.name = '123'
    vm.name = '234'
    vm.name = '123'
    ...
    

    如果我们频繁的修改一个数据,就会多次触发视图渲染dep.notify->watcher.update

    这样就会降低性能,因此就需要采用异步更新策略,仅仅在最后执行一次视图更新操作。

  2. 思路

    当数据变化时,先将数据变更的逻辑缓存下来,不直接处理,如果有相同的数据更新进行合并,在最后仅执行一次视图更新。

  3. 缓存watcher更新逻辑

    思路:将watcher集中缓存到一个队列中,在缓存过程中进行合并,最后一次性执行。

    queueWatcher方法:缓存队列,用于watcher的去重和缓存(唯一标识id)

    let queue = []; // 用于缓存渲染watcher
    let has = []; // 存放watcher唯一标识(id),用于watcher的查重
    let pending = false; // 防抖 等待状态标识,用于控制setTimeout直走一次
    function queueWatcher(watcher) {
      const id = watcher.id; // 获取watcher的id
      if (!has[id]) { // has对象没有当前watcher
        queue.push(watcher); // 缓存watcher。但不调用
        has[id] = true; // 缓存标记
    
        if (!pending) { // 不需要等待,相当于防抖策略,只执行一次
          nextTick(flushSchedulerQueue()); // 执行函数(宏任务)
        }
    
        pending = true; // 首次进入被置为true,使微任务执行完成宏任务执行
      }
    }
    

    解释一下pending:

    • queueWatcher方法中,同一watcher只会保存一次,不同的watcher就会多次加入到queue中,pending标记用于控制setTimeout中的watcher批量执行逻辑仅执行一次,相当于防抖策略
    • nextTick使一个宏任务,相当于异步代码,当全部watcher存入队列中,就会执行内部的批量执行逻辑。

    然后需要在Watcher中封装一个run方法:

      run() {
        let newValue = this.get();
        if (this.user) {
          this.cb(vm, newValue, oldValue);
        }
      }
    
  4. flushSchedulerQueue方法。

    将刷新队列逻辑抽取出来封装到flushSchedulerQueue方法中

    function flushSchedulerQueue() {
      let flushQueue = queue.slice(0);
      flushQueue = [];
      has = {};
      peding = false;
      flushQueue.forEach((q) => q.run());
    }
    
  5. nextTick封装

    在对异步任务进行封装:

    export function nextTick(cb) {
      callbacks.push(cb);
      if (!waiting) {
        timerFunc();
        wating = true;
      }
    }
    

    针对不同的异步任务进行分类:

    let timerFunc;
    // promise
    if (Promise) {
      timerFunc = () => {
        Promise.resolve().then(flushCallbacks);
      };
        // MutationObserver
    } else if (MutationObserver) {
      let observer = new MutationObserver(flushCallbacks); // 异步执行
      let textNode = document.createTextNode(1);
      observer.observe(textNode, {
        characterData: true,
      });
      timerFunc = () => {
        textNode.textContent = 2;
      };
       // setImmediate
    } else if (setImmediate) {
      timerFunc = () => {
        setImmediate(flushCallbacks);
      };
        
      // 最后setTimeout
    } else {
      timerFunc = () => {
        setTimeout(flushCallbacks);
      };
    }
    

标签:timerFunc,异步,缓存,watcher,源码,let,vue2,id
From: https://www.cnblogs.com/dgqp/p/17334426.html

相关文章

  • 源码共读|vue2 工具函数
    前言本期源码共读的课程是学习vue2中的工具函数,学习优秀开源项目的代码的写作思路,看看他们在书写代码中都会考虑到那些问题。资源:源码位置:vue/util.tsatmain·vuejs/vue(github.com)学习目标分析源码学习源码中优秀代码和思想分析源码代码使用Typescript编写,......
  • 知识付费小程序源码资源共享会员积分广告小程序定制开发源码二开
    资源分享可以在后台添加各种资源,如风景,写真,cos,壁纸,各种链接。后台可以设置这些资源如何观看,免费,看广告,VIP广告设置可以添加各种广告,可以在广告设置里设置好广告id还有广告应用场景。VIP设置管理员可以在后台更改用户的VIP设置,也可以设置卡密,让用户自行解锁vip,也可以设置积分,让用户......
  • 降低就医门槛,提高医疗效率,互联网医院源码应用案例分享
    互联网医院系统源码是基于最新的Web技术和云计算技术所构建的一种全新的医疗信息化平台。该平台可以通过网页、移动APP等多种方式,为患者提供在线预约挂号、线上问诊、电子处方、在线支付等一系列便捷、快速、安全的医疗服务。该系统源码的设计理念是以患者为中心,将医院的各个科室、......
  • ConcurrentHashMap源码&底层数据结构分析
    ConcurrentHashMap:线程安全的HashMap1.存储结构 ConcurrnetHashMap由很多个Segment组合,而每一个Segment是一个类似于HashMap的结构,所以每一个HashMap的内部可以进行扩容。但是Segment的个数一旦初始化就不能改变,默认Segment的个数是16个,你也可以认为Concu......
  • 从医疗服务到健康管理:互联网医院系统源码的应用探究
    随着互联网技术的快速发展,互联网医院系统逐渐成为医疗服务的新模式。相较于传统医疗服务,互联网医院系统具有更为便捷、高效、个性化的优势,能够为用户提供更加全面、精细的健康管理服务。本文将探究互联网医院系统源码的应用现状和未来发展方向。一、基本概念互联网医院系统源码,是指......
  • 视频直播系统源码,CSS3如何调整背景图片大小
    视频直播系统源码,CSS3如何调整背景图片大小1.lengthlength:设置背景图片的高度与宽度。第一个值设置宽度,第二个值为高度。如果只给出第一个值,那么第二值则设置为auto(自动)。 举例,将背景图片改为20emx20em(默认1px=.05em)       width:30em;      ......
  • 提高kafka消费速度之从源码去了解Spring-kafka的concurrency参数
    网上看到这篇文章,觉得很不错,这里转载记录一下。转自:提高kafka消费速度之从源码去了解Spring-kafka的concurrency参数-简书第一部分、引言    在spring应用中,如果我们需要订阅kafka消息,通常情况下我们不会直接使用kafka-client,而是使用了更方便的一层封装spring-kafk......
  • LWC_004_异步等待
    constpromise=newPromise((resolve,reject)=>{setTimeout(()=>{this[NavigationMixin.Navigate]({type:'standard__webPage',......
  • springboot项目 宿舍管理系统 (源码+数据库文件+1w字论文+ppt)
    来了就点个赞再走呗,即将毕业的兄弟有福了文章底部获取源码springboot项目宿舍管理系统(源码+数据库文件+1w字论文+ppt)技术框架:java+springboot+vue+mysql后端框架:SpringBoot、SpringMVC、MyBatisPlus前端界面:vue、BootStrap、jQuery、ajxs系统共分为三种用户系统主要功......
  • 【Vue2.x源码系列06】计算属性computed原理
    上一章Vue2异步更新和nextTick原理,我们介绍了JavaScript执行机制是什么?nextTick源码是如何实现的?以及Vue是如何异步更新渲染的?本章目标计算属性是如何实现的?计算属性缓存原理-带有dirty属性的watcher洋葱模型的应用初始化在Vue初始化实例的过程中,如果用户options选......