节流

隆儿
• 阅读 1591

throttle 的中心思想在于:在某段时间内,不管你触发了多少次回调,我都只认第一次,并在计时结束时给予响应。

先给大家讲个小故事:现在有一个旅客刚下了飞机,需要用车,于是打电话叫了该机场唯一的一辆机场大巴来接。司机开到机场,心想来都来了,多接几个人一起走吧,这样这趟才跑得值——我等个十分钟看看。于是司机一边打开了计时器,一边招呼后面的客人陆陆续续上车。在这十分钟内,后面下飞机的乘客都只能乘这一辆大巴,十分钟过去后,不管后面还有多少没挤上车的乘客,这班车都必须发走。

在这个故事里,“司机” 就是我们的节流阀,他控制发车的时机;“乘客”就是因为我们频繁操作事件而不断涌入的回调任务,它需要接受“司机”的安排;而“计时器”,就是我们上文提到的以自由变量形式存在的时间信息,它是“司机”决定发车的依据;最后“发车”这个动作,就对应到回调函数的执行。

总结下来,所谓的“节流”,是通过在一段时间内无视后来产生的回调请求来实现的。只要一位客人叫了车,司机就会为他开启计时器,一定的时间内,后面需要乘车的客人都得排队上这一辆车,谁也无法叫到更多的车。

对应到实际的交互上是一样一样的:每当用户触发了一次 scroll 事件,我们就为这个触发操作开启计时器。一段时间内,后续所有的 scroll 事件都会被当作“一辆车的乘客”——它们无法触发新的 scroll 回调。直到“一段时间”到了,第一次触发的 scroll 事件对应的回调才会执行,而“一段时间内”触发的后续的 scroll 回调都会被节流阀无视掉。

理解了大致的思路,我们现在一起实现一个 throttle:

// fn是我们要包装的回调函数事件,Interval是我们要传入的时间间隔
function throttle(fn, Interval) {
// 记录上一次调用的时间;

let last = 0;
return function() {
    // 保存上下文的this
    let context = this
    // 保存传入的参数
    let args = arguments;
    // 保存调用时的时间;
    let now = + new Date;
    // 判断上一次调用时间和当前调用时间对比
    if (now - last > Interval) {
    // 更新最后一次调用时间;
        last = now;
        fn.apply(context, args);
    }
}

}
// 用throttle来包装scroll的回调
let better_scroll = throttle(() => {console.log('触发了滚动事件'), 1000});
document.addEventListener('scroll', better_scroll);

点赞
收藏
评论区
推荐文章
Irene181 Irene181
4年前
盘点3个可以操作JavaScript的Python库
前言我们都知道Python可以很轻松的实现某些功能,而且还可以编写网页,比如Remi,Pysimplegui,但是操作JavaScript这种浏览器的脚本语言,还是第一次听说,小编也是第一次听说,于是就跟大家脑补这一知识。一、PyExecJS是一个可以执行JavaScript脚本的Python模块,可以与网页上的JavaScript进行交互,这样就能更加
待兔 待兔
11个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Wesley13 Wesley13
3年前
CRF++官方文档
前言  CRF是著名的条件随机场的开源工具,也是目前综合性能最佳的CRF工具。在这里我们简单介绍一下windows系统下CRF的使用。一、工具包的下载:CRF的工具有两种,一种是支持Linux环境的,一种是支持Windows环境的,大家可以自行根据自己的系统进行下载。(在此我下载的是CRF
Stella981 Stella981
3年前
JavaScript定时器及回调用法
JavaScript定时器及回调用法循环定时任务//假设现在有这样一个需求:我需要请求一个接口,根据返回结果判断需不需要重复请求,直到达到某一条件为止,停止请求执行某操作<scripttype"text/javascript"vartimer;
Wesley13 Wesley13
3年前
Java简单实现滑动窗口
由于最近有一个统计单位时间内某key的访问次数的需求,譬如每5秒访问了redis的某key超过100次,就取出该key单独处理。这样的单位时间统计,很明显我们都知道有个边界问题,譬如5秒内100次的限制。刚好前4.99秒访问都是0,最后0.01秒来了100次,5.01秒又来了100次。也就是访问有明显的毛刺情况出现,为了弱化这个毛刺情况,我们可以采用滑动
Wesley13 Wesley13
3年前
5分钟进阶3Par RAID
大家周三好。今天在贵阳和网友聚会未果(网友临时去紧急处理ORACLERAC问题去了,哎,IT都是苦逼的命啊)。西瓜哥空着肚子去了机场,发现机场居然有临时工位,太贴心了。本来打算写今天的文章,但是好像不能上传图片,罢了。回到帝都,发现空中看夜景真是漂亮,灯火通明,美轮美奂。可惜不能开手机拍照。看来APEC和风的效果一样,O(∩\_∩)O哈!
Stella981 Stella981
3年前
HanLP分词工具中的ViterbiSegment分词流程
本篇文章将重点讲解HanLP的ViterbiSegment分词器类,而不涉及感知机和条件随机场分词器,也不涉及基于字的分词器。因为这些分词器都不是我们在实践中常用的,而且ViterbiSegment也是作者直接封装到HanLP类中的分词器,作者也推荐使用该分词器,同时文本分类包以及其他一些自然语言处理任务包中的分词器也都间接使用了ViterbiSegment
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
使用天翼云主机组功能让云主机不放在同一个篮子里
1958年2月6日,英国欧洲航空公司609次航班在西德慕尼黑机场第三度尝试起飞时失败撞毁,机上44名乘客及机组人员当中23人遇难,遇难者中包括著名的英超球队曼联的8名球员及3名职员,这场空难给曼联造成了毁灭性的的打击,使得曼联队在很多年内都无法翻身。这场空难后,很多球队有了不成文的规定,乘坐飞机时不要所有队员乘坐同一架飞机。说完了这个故事,那这和我们今天的主
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究