reselect 和 computed 都是为了缓存计算的结果,再数据源没有修改的状况下,不执行计算的过程,直接拿到计算结果。vue
用代码解释使用计算属性缓存
class computed {
constructor() {
this.getValue()
}
start = 1
res = null
getValue() {
let res = this.start
for (let i = 1; i < 100; i++) {
res = res * i
}
this.res=res
return this.res
}
}
var a =computed()
//之后能够直接从value取值,只须要计算一次
console.log(a.res)
复制代码
常规函数返回bash
function getValue(start){
let res=start
for(let i =1;i<100;i++){
res=res*i
}
return res
}
//每次取值,都要跑一遍函数
console.log(getValue())
//固然你也能够 const value =getValue(),囧。
复制代码
毫无疑问,在使用计算属性,处理大批量数据的时候,明显优于第二种直接函数求值。框架
问题是:如何判断值是取缓存,仍是从新求值。函数
好比上文的 形参 start 发生了变化,计算属性中的value如何变化?ui
computed 是拦截 set (在第一次求值的过程当中,触发了 get 依赖收集) reselect 是判断传入的变量(好比判断第一次的 start 与新传入的 start,是否相同)this
在对 start 进行赋值的时候,直接触发计算过程spa
class computed {
constructor() {
this.getValue()
}
setStart(value){
this.start=value
return this.getValue()
}
start = 1
res = null
getValue() {
let res = this.start
for (let i = 1; i < 100; i++) {
res = res * i
}
this.res=res
return this.res
}
}
var a =computed()
console.log(a.res)
console.log(a.setStart(5))
console.log(a.res)
复制代码
const reselectCreate = createSelector(...arg , fn) //整个业务中,只执行一次
const reselect =reselectCreate(state) //在不一样组件中,进行屡次初始化
// 这里的 fn 等于 computed 中的 getValue
// 而这里的 arg 等于 computed 中的 start
复制代码
问题是 reselect 是如何进行缓存判断的?code
每次传入state的时候,会先执行 arg 中的函数(主要是取值,不涉及运算)并缓存 arg 的结果,对象
若是arg的结果一致,则跳过fn的求值过程(输入源不变,不必再跑一次),返回旧值。
若是不一致,则触发计算,返回新的值
因此这里通常是 === 进行缓存命中,但这个其实有个问题,就是引用类型。
若是传入的都是同一个对象,因为引用地址都是一致的,
若是对象内的属性修改了,所以并不会触发从新求值的过程,对于新人而言,很容易踩坑。
因此,使用 reselect 库的时候,通常会引用另外一个第三方库 immutable.js 。
因此总的来讲...vue,在计算缓存这方面来讲,有巨大的框架思想特色。
不得不说set劫持实现缓存,的确比判断结果要方便许多