淺聊快取函式
持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第9天,點選檢視活動詳情
前文,我們已經聊過了:柯里化函式、偏函式,根據高階函式的定義:
高階函指使用其他函式作為引數、或者返回一個函式作為結果的函式。
柯里化函式、偏函式,都是妥妥的高階函式!傳入一個原函式,返回一個新函式。新函式繼承了原函式的能力,又發展出不同的新能力!!
牛哇牛哇,初級前端開發,用函式封裝過程,高階前端開發,用函式封裝函式。
本篇再介紹一個新的高階函式 —— 快取函式
什麼是快取函式?什麼情況下需要用到快取函式?
本篇將用以下這個場景來解釋:
比方說,我們這裡有一個非常耗時的計算函式:
``` const calculate = (num)=>{ const startTime = new Date() for(let i=0;i<num;i++){} // 大數計算 const endTime = new Date() return endTime - startTime } console.log(calculate(10_000_000_000))
// 10465 ```
遍歷數字 100 億,需耗時 10s +,打印出這個值;
問:有什麼辦法能夠快取下來這個值,等到下次再次呼叫 calculate(10_000_000_000)
的時候,不需要再次進行計算,直接就輸出這個計算結果??
有人說:著還不簡單嗎,直接把結果付給一個變數,let result = calculate(10_000_000_000)
,下次直接拿 result
的值不就行了嗎?
從實現上講,當然是可以的;不過,從設計模式的角度來講,就不太ok了!
為什麼?
因為宣告 result
變數作為一個全域性變數要一直存在,不管未來你用或者不用,它都存在著,佔用著記憶體;
設想下,如果有 N 個大數的計算,要寫 N 個變數去存嗎?即使有一些是後面不會再重複被呼叫了的。
let result = calculate(10_000_000_000)
let result1 = calculate(10_000_000_0000)
......
let resultN = calculate(10_000_000_0000...000)
又有朋友說了:“我有好主意”!
我直接宣告一個快取物件,再改寫 calculate
函式內部,計算的時候判斷一下,算過了的,就從物件裡面拿,沒算過的,才會進行計算。
程式碼如下:
``` let cacheObj = {}
const calculate = (num)=>{ if(!cacheObj[num]){ const startTime = new Date() for(let i=0;i<num;i++){} const endTime = new Date() cacheObj[num] = endTime - startTime } return cacheObj[num] } ```
本瓜不得不說:你這孩子打小就聰明!
但是,忘記開閉原則了嗎?我們儘量要少修改原函式,而是儘量在其基礎上去拓展它。
這次是 calculate
函式需要快取,下次,可能是 balculate
或 dalculate
,難道還要去改這些函式的內部判斷嗎?
當然不!!快取函式就是來解決這種困境的!!
程式碼如下:
``` / * 快取函式 cashed /
function cached(fn){ // 傳入需要快取結果的函式
const cacheObj = Object.create(null); // 建立一個物件
return function cachedFn (str) { // 返回回撥函式 if ( !cacheObj [str] ) { // 在物件裡面查詢,函式結果是否被計算過 let result = fn(str); cacheObj [str] = result; // 沒有則要執行原函式,並把計算結果快取起來 } return cacheObj [str] // 被快取過,直接返回 } }
// calculate 計算大數的函式(也可以叫原函式)
const calculate = (num)=>{
const startTime = new Date()
for(let i=0;i<num;i++){}
const endTime = new Date()
return endTime - startTime
}
// 經過快取函式 cashed 將原函式 calculate 封裝,讓原函式具有快取的新功能
let cashedCalculate = cached(calculate)
cashedCalculate(10_000_000_000) // 10465 ```
計算結果,就已經被快取到 cashedCalculate
裡面了,我們再次呼叫:
cashedCalculate(10_000_000_000) // 10465
會立即得到計算結果 !
小結:
哈哈,就是這樣巧妙的思路,如果問快取函式的究極奧義是啥?
本瓜會答:是閉包!閉包太強了,用 cached 函式處理 calculate 的時候,就留下了一個閉包物件 cacheObj ,一直被儲存著。並且返回的是回撥函式,一樣去接收後續的引數。
這樣,既避免了多次建立全域性變數,也避免了多次修改原函式內部。
用函式封裝函式,高階!!
OK,以上便是本篇分享。點贊關注評論,為好文助力👍
我是掘金安東尼 🤠 100 萬閱讀量人氣前端技術博主 💥 INFP 寫作人格堅持 1000 日更文 ✍ 陪你一起度過漫長歲月 🌏
- ChatGPT 不過如此,Kosmos-1 更勝一籌?微軟這波又贏了
- “ChatGPT 們” 所需算力真是“貴滴誇張”!
- 國內有哪些對標 ChatGPT 的大語言模型? 5 大競品
- 常用!提前 reject promise 的 2 種場景,收藏等於學會
- 程式設計開發新朋友 —— ChatGPT 和 NotionAI 實戰
- 為什麼我更推薦 Notion AI 勝於 ChatGPT ?
- 推薦 5 個你大概率沒見過的免費 API ,一鍵獲取資料!
- ✨從純函式講起,一窺最深刻的函子 Monad
- 神馬?要退役 JavaScript ?!誰人出此狂言?!
- 寫出乾淨的 JavaScript 5 個小技巧
- 想要白嫖正則是吧?這一次給你個夠!
- 淺聊快取函式
- JavaScript 中如何取消請求
- 知其然,而知其所以然,JS 物件建立與繼承【彙總梳理】
- 10 個 Reduce 常用“奇技淫巧”
- 萬字年中總結,共勉
- 4 個 JavaScript 最基礎的問題 —— Eric Elliott
- 日拱演算法:搜尋二維矩陣 II
- 日拱演算法:多數元素
- 日拱演算法:只出現一次的數字