节流,防抖
考虑一个场景,滚动事件中会发起网络请求,但是我们并不希望用户在滚动过程中一直发起请求,而是隔一段时间发起一次,对于这种情况我们就可以使用节流。
// 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
)
复制代码
考虑一个场景,有一个按钮点击会触发网络请求,但是我们并不希望每次点击都发起网络请求,而是当用户点击按钮一段时间后没有再次点击的情况才去发起网络请求,对于这种情况我们就可以使用防抖。
// 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-thunk
这个函数的作用是改写redux的 dispatch,兼容异步action creator
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一致但其实已经修改过的函数。