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劫持實現緩存,的確比判斷結果要方便許多