记录--为啥面试官总喜欢问computed是咋实现的?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
从computed的特性出发
computed
最耀眼的几个特性是啥?
1. 依赖追踪
import { reactive, computed } from 'vue' const state = reactive({
a: 1,
b: 2,
c: 3,
})
const sum = computed(() => {
return state.a + state.b
})
我们定义了一个响应式数据state
和一个计算属性sum
, Vue会自动追踪sum
依赖的数据state.a
和state.b
,并建立相应的依赖关系。
也就是只有state.a
和state.b
发生变化的时候,sum
才会重新计算而state.c
任由它怎么变,sum
都将丝毫不受影响。
2. 缓存
还是上面的例子,如果state.a
和state.b
打死都不再改变值了,那么我们读取sum
的时候,它将会返回上一次计算的结果,而不是重新计算。
3. 懒计算
这个特性比较容易被忽略,简单地说只有计算属性真正被使用(读取)的时候才会进行计算,否则咱就仅仅是定义了一个变量而已。
import { reactive, computed } from 'vue' const state = reactive({
a: 1,
b: 2,
c: 3
}) const sum = computed(() => {
console.log('执行计算')
return state.a + state.b
}) setTimeout(() => {
// 没有读取sum.value之前,sum不会进行计算
console.log('1-sum', sum.value)
// 我们改变了a的值,但是sum并不会立刻进行计算
state.a = 4 setTimeout(() => {
// 而是要等到再次读取的时候才会触发重新计算
console.log('2-sum', sum.value)
}, 1000)
}, 1000)
挨个实现computed特性
1. 懒计算
我们依旧围绕effect
函数来搞事情,到目前为止,effect
注册的回调都是立刻执行。
const state = reactive({
a: 1,
b: 2,
c: 3
})
// 有没有很像计算属性的感觉
const sum = effect(() => {
console.log('执行计算') // 立刻被打印
const value = state.a + state.b
return value
}) console.log(sum) // undefined
想要实现computed
的懒执行,咱们可以参考上篇文章Vue3:原来你是这样的“异步更新”的思路,添加一个额外的参数lazy
。
它要实现的功能是:如果传递了lazy
为true
,副作用函数将不会立即执行,而是将执行的时机交还给用户,由用户决定啥时候执行。
当然啦!回调的结果我们也应该一并返回(例如上面的value值)
你能想象,我们仅仅需要改造几行代码就能离computed
近了一大步。
const effect = function (fn, options = {}) {
const effectFn = () => {
// ... 省略
// 新增res存储fn执行的结果
const res = fn()
// ... 省略
// 新增返回结果
return res
}
// ... 省略
// 新增,只有lazy不为true时才会立即执行
if (!options.lazy) {
effectFn()
}
// 新增,返回副作用函数让用户执行
return effectFn
}
测试一波
const state = reactive({
a: 1,
b: 2,
c: 3,
});
// 有没有很像计算属性的感觉
const sum = effect(() => {
console.log("执行计算"); // 调用sum函数后被打印
const value = state.a + state.b;
return value;
}, {
lazy: true
});
// 不执行sum函数,effect注册的回调将不会执行
console.log(sum()); // 3
2. 依赖追踪
咱们初步实现了懒执行的特性,为了更像computed
一点,我们需要封装一个函数。
function computed (getter) {
const effectFn = effect(getter, {
lazy: true,
}) const obj = {
get value () {
return effectFn()
}
} return obj
}
这就有点那么味道啦!
测试一波
可以看到computed
只会依赖state.a
和state.b
,而不会依赖state.c
,这得益于我们前面几篇文章实现的响应式系统,所以到了计算属性这里,我们不用改动任何代码,天然就支持。
不过还是有点小问题,我们读取了两次sum.value
,sum却被执行了两次,这和computed
缓存的特性就不符了。
别急,马上就要实现了这个最重要的特性了。
const state = reactive({
a: 1,
b: 2,
c: 3
}) const sum = computed(() => {
console.log('执行计算')
return state.a + state.b
}) console.log(sum.value)
console.log(sum.value)
3. 缓存
回顾一下computed
的缓存特性:
- 只有当其依赖的东西发生变化了才需要重新计算
- 否则就返回上一次执行的结果。
为了缓存上一次计算的结果,咱们需要定义一个value变量,现在的关键是怎么才能知道其依赖的数据发生变化了呢?
function computed (getter) {
const effectFn = effect(getter, {
lazy: true,
})
let value
let dirty = true const obj = {
get value () {
// 2. 只有数据发生变化了才去重新计算
if (dirty) {
value = effectFn()
dirty = false
} return value
}
} return obj
}
测试一波
const state = reactive({
a: 1,
b: 2,
c: 3
}) const sum = computed(() => {
console.log('执行计算')
return state.a + state.b
}) console.log(sum.value) // 3
console.log(sum.value) // 3 state.a = 4 console.log(sum.value) // 3 答案是错误的
寄上任务调度
不得不说,任务调度实在太强大了,不仅仅可以实现数组的异步批量更新、在computed
和watch
中也是必不可少的。
function computed (getter) {
const effectFn = effect(getter, {
lazy: true,
// 数据发生变化后,不执行注册的回调,而是执行scheduler
scheduler () {
// 数据发生了变化后,则重新设置为dirty,那么下次就会重新计算
dirty = true
}
})
let value
let dirty = true const obj = {
get value () {
// 2. 只有数据发生变化了才去重新计算
if (dirty) {
value = effectFn()
dirty = false
} return value
}
} return obj
}
测试一波
const state = reactive({
a: 1,
b: 2,
c: 3
}) const sum = computed(() => {
console.log('执行计算')
return state.a + state.b
}) console.log(sum.value) // 3
console.log(sum.value) // 3 state.a = 4 console.log(sum.value) // 3 答案是错误的
完美!!!这下面试官再也难不倒我了!!!
本文转载于:
https://juejin.cn/post/7259405321020424251
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
记录--为啥面试官总喜欢问computed是咋实现的?的更多相关文章
- 基础面试,为什么面试官总喜欢问String?
关于 Java String,这是面试的基础,但是还有很多童鞋不能说清楚,所以本文将简单而又透彻的说明一下那个让你迷惑的 String 在 Java 中,我们有两种方式创建一个字符串 String x ...
- 一线大厂面试官最喜欢问的15道Java多线程面试题
前言 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得更多职位,那么你应该准备很多关于多线程的问题. 他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者 ...
- 2019年面试官最喜欢问的28道ZooKeeper面试题
前言 ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务.它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护.域名服务.分布式同步.组服务等. ZooKeeper 的 ...
- 深度分析:面试腾讯,阿里面试官都喜欢问的String源码,看完你学会了吗?
前言 最近花了两天时间,整理了一下String的源码.这个整理并不全面但是也涵盖了大部分Spring源码中的方法.后续如果有时间还会将剩余的未整理的方法更新到这篇文章中.方便以后的复习和面试使用.如果 ...
- 阿里面试官最喜欢问的21个HashMap面试题
1.HashMap 的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点.当链表长度超过 8 时,链表转换为红黑树. transient Node<K,V>\[\ ...
- 聊聊CAS - 面试官最喜欢问的并发编程专题
什么是CAS 学习Java并发编程,CAS(Compare And Set)机制都是一个不得不掌握的知识点.除了通过synchronized进行并发控制外,还可以通过CAS的方式控制,大家熟悉的Ree ...
- 2021超详细的HashMap原理分析,面试官就喜欢问这个!
一.散列表结构 散列表结构就是数组+链表的结构 二.什么是哈希? Hash也称散列.哈希,对应的英文单词Hash,基本原理就是把任意长度的输入,通过Hash算法变成固定长度的输出 这个映射的规则就是对 ...
- 走向DBA[MSSQL篇] 面试官最喜欢的问题 ----索引+C#面试题客串
原文:走向DBA[MSSQL篇] 面试官最喜欢的问题 ----索引+C#面试题客串 对大量数据进行查询时,可以应用到索引技术.索引是一种特殊类型的数据库对象,它保存着数据表中一列或者多列的排序结果,有 ...
- Java面试官最常问的volatile关键字
在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯 ...
- 大厂面试官最常问的@Configuration+@Bean(JDKConfig编程方式)
大厂面试官最常问的@Configuration+@Bean(JDKConfig编程方式) 现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法.一 ...
随机推荐
- offline 2 online | 重要性采样,把 offline + online 数据化为 on-policy samples
论文标题:Offline-to-Online Reinforcement Learning via Balanced Replay and Pessimistic Q-Ensemble CoRL 20 ...
- 【Unity3D】基于深度和法线纹理的边缘检测方法
1 前言 边缘检测特效中使用屏后处理技术,通过卷积运算计算梯度,检测每个像素周围像素的亮度差异,以识别是否是边缘像素:选中物体描边特效中也使用了屏后处理技术,通过 CommandBuffer 获取 ...
- 【Unity3D】固定管线着色器一
1 前言 着色器(Shader)是渲染管线中最重要的一环,Unity3D 底层基于 OpenGL 实现,读者可以通过 渲染管线 了解 Unity3D 渲染流程. OpenGL 1.x 为固定管 ...
- SSH通道
线下到线上 通过http协议 线上到线下 不能走http,只能通过ssh通道,建立玩ssh通道后,线上线下就可以通道ssh通道进行通信 如:线上为ssm项目 线下为linux项目,二者之间lin ...
- 以二进制文件安装K8S之高可用部署架构
在Kubernetes系统中,Master节点扮演着总控中心的角色,通过不间断地与各个工作节点(Node)通信来维护整个集群的健康工作状态,集群中各资源对象的状态则被保存在etcd数据库中. 在正式环 ...
- OpenCV计数应用 c++(QT)
一.前言 为了挑战一下OpenCV的学习成果,最经一直在找各类项目进行实践.机缘巧合之下,得到了以下的需求: 要求从以下图片中找出所有的近似矩形的点并计数,重叠点需要拆分单独计数. 二.解题思路 1. ...
- 全表查询sql执行链路排查
问题描述: 发现有sql查询全表数据,慢查询语句,根据druid上的sql监控查看到. 主要根据标红的列确定问题sql. 点击进去可以看到详细sql信息. 问题排查目标: 发现这个语句高层调用方特别多 ...
- DataGear 制作基于 three.js 的 3D 数据可视化看板
DataGear专业版 1.0.0 已发布,欢迎试用! http://datagear.tech/pro/ DataGear 支持采用原生的HTML.JavaScript.CSS制作数据可视化看板,也 ...
- 【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
问题描述 在Azure Kubernetes 服务中,创建一个Internal Load Balancer服务,使用以下yaml内容: internallb.yaml apiVersion: v1 k ...
- 【Azure API 管理】APIM中证书更新问题
问题描述 每一年到期更新域名证书,APIM会中断服务,请问如何不中断服务? 问题解答 Azure API 管理允许在受信任的根证书和中间证书存储中的计算机上安装 CA 证书,分配证书的过程可能需要 1 ...