考慮一個場景,滾動事件中會發起網絡請求,可是咱們並不但願用戶在滾動過程當中一直髮起請求,而是隔一段時間發起一次,對於這種狀況咱們就能夠使用節流。javascript
// func是用戶傳入須要防抖的函數
// wait是等待時間
const throttle = (func, wait = 50) => {
// 上一次執行該函數的時間
let lastTime = 0
return function(...args) {
// 當前時間
let now = +new Date()
// 將當前時間和上一次執行函數時間對比
// 若是差值大於設置的等待時間就執行函數
if (now - lastTime > wait) {
lastTime = now
func.apply(this, args)
}
}
}
setInterval(
throttle(() => {
console.log(1)
}, 500),
1
)
複製代碼
考慮一個場景,有一個按鈕點擊會觸發網絡請求,可是咱們並不但願每次點擊都發起網絡請求,而是當用戶點擊按鈕一段時間後沒有再次點擊的狀況纔去發起網絡請求,對於這種狀況咱們就能夠使用防抖。java
// func是用戶傳入須要防抖的函數
// wait是等待時間
const debounce = (func, wait = 50) => {
// 緩存一個定時器id
let timer = 0
// 這裏返回的函數是每次用戶實際調用的防抖函數
// 若是已經設定過定時器了就清空上一次的定時器
// 開始一個新的定時器,延遲執行用戶傳入的方法
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}
複製代碼
這個函數的做用是改寫redux的 dispatch,兼容異步action creatorredux
function createThunkMiddleware(extraArgument) {
// 這段寫法的意思是: 至關於函數柯里化將多個參數層層包裝
// return function ({
// dispatch,
// getState
// }) {
// 根據上面redux源碼 next就是 store.dispatch
// return function (next) {
// 這個時候實際返回的dispatch就被改寫成這個了: 參考redux源碼:dispatch = compose(...chain)(store.dispatch)
// return function (action) {
// 而後在這裏傳入action creator 就能夠處理函數和對象兩種狀況下而後進行異步
// if (typeof action === 'function') {
// return action(dispatch, getState, extraArgument);
// }
// return next(action);
// }
// }
// }
return ({ dispatch, getState }) => next => action => {
//判斷
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
複製代碼
這段函數的做用是在第一次調用當作中間件而後返回函數,第二次調用注入{ dispatch, getState },第三次調用的時候時候實際上是注入原生dispatch,最後返回一個跟dispatch同樣的函數,而後函數內部封裝了對同步異步的處理。同步的化就調用了第三次執行的時候注入的原生dispatch,異步的話給action creator 返回的函數注入 第二次函數調用的時候注入的dispatch。
這樣的好處是能夠在不一樣的執行時期注入不一樣的參數,而後在最後整合成跟原來dispatch一致但其實已經修改過的函數。緩存