第七章 实现effect的stop功能

news2024/9/9 1:17:45

实现effect的stop功能

通过stop函数传入effect返回的runner 再次修改响应式对象的值的时候 不会修改成功

其实主要思路就是在调用stop函数的时候将 收集的effect依赖移除掉

老样子先给上测试用例:

it('stop',()=>{
        // 通过stop函数传入effect返回的runner 再次修改响应式对象的值的时候 不会修改成功
        // 其实主要思路就是在调用stop函数的时候将 收集的effect依赖移除掉
        let dummy
        const obj = reactive({prop:1})
        const runner = effect(()=>{
            dummy = obj.prop
        })
        obj.prop = 2
        expect(dummy).toBe(2)
        stop(runner)
        obj.prop = 3
        expect(dummy).toBe(2)
        runner()
        expect(dummy).toBe(3)
})

大体stop功能实现的步骤:

1 需要在effect中导出stop函数,导出的stop函数中通过传入的runner去调用effect实例上的stop方法

2 所以需要给传入的runner挂载上effect函数

3 需要在ReactiveEffect类上提供stop方法,stop方法中要获取到对应effect的dep依赖,这就需要我们在track依赖收集的时候去做一下反向收集dep

4 最后循环deps数组中的每一个dep,进行一个effect依赖的移除

实现的部分截图说明:

image.png

image.png
以下是代码实现:

effect和stop函数的代码:

export function effect(fn,options:any = {}){
    const _effect = new ReactiveEffect(fn,options.scheduler)

    _effect.run()

    const runner:any = _effect.run.bind(_effect)

    runner.effect = _effect

    return runner
}

export function stop(runner) {
    runner.effect.stop()
}

track函数:

export function track(target,key){
    // target -> key -> dep
     let depsMap = targetMap.get(target)
     if(!depsMap){
        depsMap = new Map()
        // 没有depsMap时要加进去
        targetMap.set(target,depsMap)
     }


    let dep = depsMap.get(key)
    if(!dep){
        dep = new Set()
        depsMap.set(key,dep)
    }
    dep.add(activeEffect)
    // 这里需要反向收集一下dep
    activeEffect.deps.push(dep)
}

ReactiveEffect类中的stop函数:

stop(){
        this.deps.forEach((dep:any) => {
            dep.delete(this)
        })
}

重构

根据tdd的开发流程来说,第一步是写测试,第二步是让测试通过,第三步是对代码的一个重构,下面我们就对我们的代码进行重构,让它更有可读性

这里主要有两个优化点:

1 将移除依赖的函数抽离出来封装,更加简洁

2 使用active变量,防止使用者多次调用stop时重复触发

image.png

因为onStop功能和stop功能相关,所以就一起在这里介绍了

onstop主要就是在effect函数的第二个配置项中传入,然后当调用stop函数的时候,onStop将会被执行

接下来是onStop的测试代码:

it('onStop',()=>{
        // onstop主要就是在effect函数的第二个配置项中传入,然后当调用stop函数的时候,onStop将会被执行
        const obj = reactive({
            foo:1
        })
        const onStop = jest.fn()
        let dummy
        const runner = effect(
            ()=>{
                dummy = obj.foo
            },
            {
                onStop
            }
        )
        stop(runner)
        expect(onStop).toBeCalledTimes(1)
    })

这个实现起来就比较简单了,实现onStop的思路:

1 effect中接受onStop

2 在effect中调用stop函数的时候如果传入了onStop就执行onStop

image.png

image.png

改动只有红色部分,代码不多就不上代码了

接下来就是老规矩了,重构,这里我们有什么可以重构的呢?其实最主要可以重构的点就是effect的第二个配置项参数,因为每次多传入一个配置项时就需要我们手动的去接收一下,其实是很麻烦的。因此我们就可以使用Object.assign将传入的options加入到effect中去

如图红框:

image.png

但是一想,其实这种通用性极强的公共函数我们是可以抽离出去给所有其他模块使用:

所以我们就把他写到了shared/index.ts中的公共函数模块中去

image.png

然后直接在effect中导入使用了:

image.png

yarn test时报错问题:

最后,因为我们一直测试的是effect的测试文件(yarn test effect),这个文件的测试用例是通过的了,这时候我们这个模块的功能写完了之后,一般需要yarn test测试一下你所有功能,会不会有问题。当我们yarn test测试所有的时候就出问题了,报错如下

image.png
知道问题在哪了,那其实问题就解决了百分之90了,我们找到收集依赖的track函数,然后对activeEffect进行判断,当没有activeEffect的时候就直接return掉track,不再往下走,如图红框:

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/384440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JPG格式图片怎么弄?可以试试这些途径

在日常生活中,我们经常需要将图片转换为JPG格式,以便在各种设备上使用,因为 JPG 是一种常用的图像格式,具有广泛的兼容性和易用性。这里将介绍几种简单的方法,以帮助您将图片转换为JPG格式。方法一、使用格式转换软件转…

快速入门 Stream 流 【学习笔记】Java基础

若文章内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系博主删除。写这篇博客旨在制作笔记,方便个人在线阅览,巩固知识,无其他用途。 学习视频:【黑马 Java 基础教程…

怎么避免计算机SCI论文的重复率过高? - 易智编译EaseEditing

论文成稿前 在撰写阶段就避免重复:在撰写阶段就避免文章中的重复内容,可以减少后期修改的工作量。 在写作前,可以制定良好的计划和大纲,规划好文章的结构和内容,从而减少重复内容。 加强对相关文献的阅读 为了避免自己…

大话数据结构-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

6 最短路径 最短路径,对于图来说,是两顶点之间经过的边数最少的路径;对于网来说,是指两顶点之间经过的边上权值之和最小的路径。路径上第一个顶点为源点,最后一个顶点是终点。 6.1 迪杰斯特拉(Dijkstra&am…

【C语言】深度理解指针(上)

前言🌊谈到指针,想必大家都不陌生。它不仅是C语言的重难点,还是不少C初学者的噩梦。本期我们将深度探讨一些较为复杂的指针以及指针的妙用,带领大家感受指针的魅力😝。首先,我们先来复习复习指针的概念&…

dbutils给bean类对象赋值源码分析

本文重点 以ResultSetHandler的实现类BeanListHandler为例&#xff0c;探索dbutils的QueryRunner的实现细节&#xff0c;重点是如何给java bean类对象赋值。 public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws…

119.Android 简单的软键盘和菜单无缝切换效果,聊天界面软键盘无缝切换

//此效果主要通过动态设置windowSoftInputMode三种状态的切换实现&#xff1a;SOFT_INPUT_ADJUST_NOTHING、SOFT_INPUT_ADJUST_PAN、SOFT_INPUT_ADJUST_RESIZE。 1.第一步 导入需要用到的依赖库&#xff1a; //RecyclerView implementation com.android.support:recyclerview-…

做为骨干网络的分类模型的预训代码安装配置简单记录

一、安装配置环境 1、准备工作 代码地址 GitHub - bubbliiiing/classification-pytorch: 这是各个主干网络分类模型的源码&#xff0c;可以用于训练自己的分类模型。 # 创建环境 conda create -n ptorch1_2_0 python3.6 # 然后启动 conda install pytorch1.2.0 torchvision…

Anaconda环境配置Python绘图库Matplotlib的方法

本文介绍在Anaconda环境中&#xff0c;安装Python语言matplotlib模块的方法。 在之前的文章中&#xff0c;我们多次介绍了Python语言matplotlib库的使用&#xff1b;而这篇文章&#xff0c;就介绍一下在Anaconda环境下&#xff0c;配置matplotlib库的方法。 首先&#xff0c;打…

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual ...

目录 报错 解决 注意&#xff1a; - > 是追加的意思。 解决&#xff1a;分号结尾执行报错&#xff0c;然后重新输入正确的sql语句就可以了。 报错 在docker中部署mysql&#xff0c;创建进入mysql进行数据库查询的时候报错&#xff1a; ERROR 1064 (42000): You have a…

有趣的小知识(三)提升网站速度的秘诀:掌握缓存基础,让你的网站秒开

像MySql等传统的关系型数据库已经不能适用于所有的业务场景&#xff0c;比如电商系统的秒杀场景&#xff0c;APP首页的访问流量高峰场景&#xff0c;很容易造成关系型数据库的瘫痪&#xff0c;随着缓存技术的出现很好的解决了这个问题。 一、缓存的概念&#xff08;什么是缓存…

PyTorch保姆级安装教程

1 安装CUDA1.1 查找Nvidia适用的CUDA版本桌面右键&#xff0c;【打开 NVIDIA控制面板】查看【系统信息】查看NVIDIA的支持的CUDA的版本&#xff0c;下图可知支持的版本是 10.11.2 下载CUDACUDA下载官方网址https://developer.nvidia.com/cuda-toolkit-archive找到适合的版本下载…

第六章 effect.scheduler功能实现

effect.scheduler功能实现 主要先了解scheduler需要实现什么样的需求&#xff0c;有一下四点&#xff1a; 1 通过 effect 的第二个参数给定一个 scheduler 的 fn 2 effect 第一次执行的时候 还会执行 fn 3 当 响应式对象 set update 不执行fn 而是执行 scheduler 4 如果说…

面试问题【线程】

线程什么是进程什么是线程进程和线程的关系什么是并发和并行如何使用线程Thread 和 Runnable 两种开发线程的区别线程的生命周期什么是上下文切换什么是线程死锁如何避免死锁说说 sleep() 方法和 wait() 方法区别和共同点为什么我们调用 start() 方法时会执行 run() 方法&#…

Transformer学习

原论文&#xff1a;Attention Is All You Need。论文地址&#xff1a;https://arxiv.org/abs/1706.03762. Transformer是针对自然语言处理的&#xff0c;Google在2017年发表在Computation and Language&#xff0c;RNN模型记忆长度有限且无法并行化但是Tranformer解决了上述问…

解析几何北大第五版复习提纲

第一章 两向量向量积 向量积定义&#xff1a;a x b |a||b|sin几何意义&#xff1a;平行四边形面积性质&#xff1a; 两向量共线的充分必要条件是 a x b 0 数乘&#xff1a; 分配律&#xff1a; 求法&#xff1a;行列式 三向量混合积 混合积定义&#xff1a;对于一个六面体,…

快鲸SCRM发布口腔企业私域运营解决方案

口腔企业普遍面临着以下几方面运营痛点问题 1、获客成本居高不下&#xff0c;恶性竞争严重 2、管理系统落后&#xff0c;人员流失严重 3、客户顾虑多、决策时间长 4、老客户易流失&#xff0c;粘性差 以上这些痛点&#xff0c;不得不倒逼口腔企业向精细化运营客户迈进。 …

【LeetCode】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 p131 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/ 1. 题目介绍&#xff08;21. 调整数组顺序使奇数位于偶数前面&#xff09; 输入一个整数数组&#xff0c;实现一个函数来调整该数组中数字的顺序&…

4自由度串联机械臂按颜色分拣物品功能的实现

1. 功能说明 本实验要实现的功能是&#xff1a;将黑、白两种颜色的工件分别放置在传感器上时&#xff0c;机械臂会根据检测到的颜色&#xff0c;将工件搬运至写有相应颜色字样区域。 2. 使用样机 本实验使用的样机为4自由度串联机械臂。 3. 运动功能实现 3.1 电子硬件 在这个…

快速吃透π型滤波电路-LC-RC滤波器

π型滤波器简介 π型滤波器包括两个电容器和一个电感器&#xff0c;它的输入和输出都呈低阻抗。π型滤波有RC和LC两种&#xff0c; 在输出电流不大的情况下用RC&#xff0c;R的取值不能太大&#xff0c;一般几个至几十欧姆&#xff0c;其优点是成本低。其缺点是电阻要消耗一些…