前言: 整个六月份就水了四篇文章,这完美的证明了我六月份基本没学啥东西 。这周在工作中主要是写了消息系统模块,自己封装的,测试老发现 bug ,只能发现一个修一个,还好是小姐姐,不然都要过来揍我了,新项目可的仔细点,多看 PRD 多测试。
主题:工作中我小伙伴喜欢用 lodash 这个库,我就喜欢 ES6 ,因为在我认识中,ES6 处理数据已经挺完美了,而且一个高手还能把处理数据的代码全给压平,代码结构由立体变扁平,类似这种:
//本人项目截取片段,写的不是很好多包涵
let unReadHeadIdArr = res.data.messages.map(item=>item && item.head.id);
let allMessArrId = window.sessionStorage.getItem("allMessVisable");
allMessArrId = allMessArrId ? JSON.parse(allMessArrId) : [];
let unReadHeadId = unReadHeadIdArr.filter(item=>!allMessArrId.includes(item));
其实我也是不想看 lodash,immediate这种第三方库,那么多 API,emmm,但是 ES6 也不是完美无缺的,其中就少了一个很重的东西,防抖和节流函数。而恰恰这两个函数在项目中很常用到。这时候就能体验到 lodash 的便捷了,虽然它的代码体积很大。最近我在写登陆模块的按钮的时候就体会很深,想起我以前技术差的时候能把项目模块功能写出来就很 happy 了,现在开始有点精力去注意这些边边角角了,that's brilliant。本着学习的态度,当然的研究下 debounce and throttle
的源码了,因为如果不使用 lodash 第三方库的时候,我们可以在项目中 util 文件夹中,放一些项目工具函数的地方,引入这两个函数,然后愉快的使用。
underscore
和 lodashjs
这两个库都有 debounce and throttle
用法都差不多,就以 underscore
为例进行研究吧。
先推荐一个视频教程看看思路:手写函数防抖和节流——小马哥_老师
还有一个文字版的教程也可以看看:underscore 函数去抖的实现
在去官网看看 debounce 和 throttle 的用法:
- underscore官网
- lodash 官网
我了解的防抖和节流:
- 防抖:多次触发,只执行一次。
- 节流:一直触发期间合理执行。
这是个 underscore CDN 可以打开对照源码阅读:underscore
一、基本骨架
鼠标移动无限次触发计数显示:
debounce and throttle
二、debounce 实现
underscore 中 debounce 函数有三个参数:debounce(需要防抖的函数,间隔时间,执行顺序)
首先讲下实现的三个难点:
- 需要防抖函数中的 this;
- 需要防抖函数的事件对象 event ;
- 需要防抖函数返回结果不能改变
一版:能防抖、能绑定 this 和 event
二版:增加函数返回值
如果需要防抖的函数 wirteCount
函数有返回值我们也应该予以保留。
function wirteCount(){
this.innerHTML = count++;
return "我需要返回一些东西";
}
二版实现,就增加了一个 result 变量来接收 wirteCount
函数返回值:
最最难的点来了,debounce 第三个参数的实现,定义防抖函数刚触发就执行,还是触发之后等 wait 秒在执行。
三版:
debounce and throttle
四版:现在就差一个取消操作了,取消操作我们需要做些改变,需要把 debounce 函数返回的函数提取出来进行扩展。
debounce and throttle
debounce 到此就写完了,到此你能看懂几乎所有第三方源码实现了,因为它们的实现基本都大同小异。
三、throttle 实现
你一定认为 debounce 都实现了,throttle 就不是很难了,No no 。throttle 最难的是第三个参数的实现思路,先来看看 underscore 中 throttle 的用法,throttle 前两个参数和 debounce 没啥区别,区别在于第三个参数不是 boolean 值,而是一个对象_throttle(func,wait,{leading: true,trailing:true})
leading 表示事件触发立即执行 func ,trailing 表示最后离开是否触发 func。两个都默认为 true。
前置知识:
和 debounce
函数一样,也有三个难点:
- 需要防抖函数中的 this,通过 apply 绑定;
- 需要防抖函数的事件对象 event ,通过 apply 传入;
- 需要防抖函数返回结果不能改变
现在这个就比较简单了,通过这三个变量 let ctx, args, result;
完美接受实现,下面主要关注实现 throttle
第三个参数的实现。
3.1 leading 实现
leading :函数一触发就立即执行 func ,然后稳定的间隔执行 func ,最后一次离开不执行 func。
下面通过时间戳来实现的:
- 刚开始
old = 0
条件now - old > wait
一定为真,也就是 func 立即触发。 -
now - old > wait
第一次为真之后,func 就能稳定执行。 - 最后离开不会执行 func ,快速进入快速离开,你会发现 func 只在进入执行了一次。
debounce and throttle
3.2 trailing 的实现
- 第一次进入不触发,然后稳定的间隔执行 func ,最后一次离开执行 func。
- 快速进入快速离开,你会发现 func 只在离开后执行了一次。
debounce and throttle
3.3 leading 和 trailing 二合一实现 throttle
debounce and throttle
写作于北京昌平区 当前时间 Saturday, June 27, 2020 02:29:33