专栏首页Vue开发社区vue3.0的异步更新原理
原创

vue3.0的异步更新原理

今天我们简单了解下vue3.0的异步更新原理,了解一下effectwatchEffect的特点以及最主要queueFlush函数的实现(函数名字本意就是: 排队刷新

effect特点

import { effect, reactive } from './reactivity';
let state = reactive({ name: 'zf', age: 11 })
effect(() => {
    console.log(state.name);
})
state.name = 'zf';
state.name = 'jw';
state.name = 'jg';

每次更新状态,都会重新运行effect。如果要是effect中包含渲染逻辑,可能会导致多次更新视图

watchEffect

import { effect } from "./reactivity";
export function watchEffect(effect, options) {
    return doWatch(effect, null, options);
}
let postFlushCbs = [];
function queuePostFlushCb(cb){
    postFlushCbs(cb); // 将effect放到数组中进行刷新
    queueFlush();
}
function doWatch(source, cb, options) { // 做watch
    let getter;
    if (isFunction(source)) {
        getter = () => source();
    }
    let scheduler = (job) => queuePostFlushCb(job);
    const runner = effect(getter,{ // 创建一个effect
        lazy:true, 
        computed: true,
        scheduler // 自定义scheduler
    })
    runner();
}

watchEffect也是effect,只是自定义了scheduler函数

queueFlush实现

let isFlushPending = false; // 是否正在等待刷新
let isFlushing = false; // 是否正在刷新
const p = Promise.resolve();
function nextTick(fn) {
    return fn ? p.then(fn) : p
}
function flushPostFlushCbs(){
    if(postFlushCbs.length){ // 队列有值进行队列刷新
        const cbs = [...new Set(postFlushCbs)];
        postFlushCbs.length = 0;
        for(let i = 0; i < cbs.length;i++){
            cbs[i]();
        }
    }
}
function flushJobs() {
    isFlushPending = false; // 开始执行任务
    isFlushing = true; // 正在刷新
    flushPostFlushCbs(); // 刷新队列
    isFlushing = false; // 刷新完毕
}
function queueFlush() {
    if (!isFlushPending && !isFlushing) {
        isFlushPending = true;
        nextTick(flushJobs); // 稍后刷新任务队列
    }
}

nextTick本质原理就是个promise(微任务),这里会将effect 暂存起来并进行去重之后执行。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一文搞懂CDN加速原理

    通过以上的分析我们可以得到,为了实现对普通用户透明(使用缓存后用户客户端无需进行任何设置)访问,需要使用DNS(域名解析)来引导用户来访问Cache服务器,以实...

    前端老道
  • 学会这几个JS知识点,面试包你通过

    “ 关注 前端开发社区 ,回复 '领取资源',免费领取Vue,小程序,Node Js,前端开发用的插件以及面试视频等学习资料,让我们一起学习,一起进步

    前端老道
  • JS数组的几个牛逼操作 | 面试高频

    “ 关注 前端开发社区 ,回复 '领取资源',免费领取Vue,小程序,Node Js,前端开发用的插件以及面试视频等学习资料,让我们一起学习,一起进步

    前端老道
  • 【独家编译】美国农业大数据公司FarmLogs获C轮2200万美元融资,让数据改变传统农业

    数据猿导读 FarmLogs 依靠移动互联网收集农业产生产管理数据,如耕种、 施肥、 浇水、 种植、 喷洒、收割数据和外接的土壤数据、气象数据,并将其实时呈现在...

    数据猿
  • 机器学习中的数据不平衡解决方案大全

    在机器学习任务中,我们经常会遇到这种困扰:数据不平衡问题。 数据不平衡问题主要存在于有监督机器学习任务中。当遇到不平衡数据时,以总体分类准确率为学...

    机器学习算法工程师
  • 开发 | 如何解决机器学习中的数据不平衡问题?

    在机器学习任务中,我们经常会遇到这种困扰:数据不平衡问题。 数据不平衡问题主要存在于有监督机器学习任务中。当遇到不平衡数据时,以总体分类准确率为学习目标的传统分...

    AI科技评论
  • 如何解决机器学习中的数据不平衡问题?

    在机器学习任务中,我们经常会遇到这种困扰:数据不平衡问题。 数据不平衡问题主要存在于有监督机器学习任务中。当遇到不平衡数据时,以总体分类准确率为学习目标的传统分...

    AI研习社
  • Mac安装多版本go

    用户2187945
  • laravel-admin利用ModelTree实现对分类信息的管理

    app/Admin/Controllers/CategoriesController.php

    砸漏
  • Apache(2)——进程与模块

    当我们安装好Apache后,Apache会给我们创建一个Apache用户和Apache用户组。 可以查看最新的用户信息:

    gzq大数据

扫码关注云+社区

领取腾讯云代金券