文档章节

利用throttle和debounce实现延迟请求

zimingforever
 zimingforever
发布于 2017/02/10 13:56
字数 358
阅读 675
收藏 0

当你在前端点击一个搜索往后面发送请求的时候会触发一个像后端的请求,当你不在前端做一些控制的时候,就会发现会发送特别多的请求

 

比如一个人员搜索,虽然前端控制了当搜索字符大于3个字的时候才发送,但是后续还是会出现如下问题。

以前的实现方式比较挫,定义一个timer,当请求结束后清除timer,再继续发送请求,避免一次发送多个请求

onSearch(value) {
  const props = this.props;
  if (this.timer) {
    clearTimeout(this.timer);
  }
  this.timer = setTimeout(() => {
    xxx
  }, 300);
}

这里介绍一个类库,利用throttle和debounce解决 https://www.npmjs.com/package/throttle-debounce

throttle的原理如下

无论提交如何频繁,任意两次有效提交的间隔时间必定会大于或等于某一时间间隔;即以一定频率提交。
module.submit = throttle(150, function() {
  // todo})
如果客户发送每隔100毫秒发送过来10次请求,此模块将只接收其中6个(每个在时间线上距离为150毫秒)进行处理。

debounce的原理如下

任意两次提交的间隔时间,必须大于一个指定时间,才会促成有效提交;即不给休息不干活。
module.submit = debounce(150, function() {
  // todo})

利用debounce更改新代码

function handleUserSearchChange(value) {
    dispatch({
      type: 'implatation/userSearch',
      payload: {
        searchText: value,
      },
    });
}
 
 
onSearch={debounce(1000,handleUserSearchChange)}

 

© 著作权归作者所有

zimingforever
粉丝 142
博文 266
码字总数 315040
作品 0
杭州
程序员
私信 提问
加载中

评论(4)

zimingforever
zimingforever 博主

引用来自“小互哦”的评论

用的loadsh的debounce,出现一个问题,试了博主的debounce,问题依旧:dispatch会使debounce的前沿失效(环境:antd+dva)。而博主的这个插件的debounce默认是后沿。所以最后一个例子onSearch={debounce(1000, true, handleUserSearchChange)}会失效。猜测原因是派遣使状态改变,函数刷新重置,而后沿因为直接阻止,所以没发生派遣,所以有效。现在还不知道怎么解决,还请博主指点。

引用来自“王小明123”的评论

不是很懂你的描述,失效具体是是什么情况,我的控件交给了antd的管控,用了form的特性。所以我不需要自己维护控件的状态。

我只需要在控件发生onserch或者onclick的时候延迟调用后台服务即可,这时候确实是有state变化的,但是并没有阻断发生请求。

引用来自“小互哦”的评论

我现在的业务逻辑是提交表单,防止连续点击提交。所以用了debounce,就拿博客最后一个为例,如果改为前沿(第二个参数改为true),因为提交函数里面肯定有派遣(后台请求),这样debounce的防抖效果就会失效。只要有派遣发生,哪怕里面是空的,也会引起state刷新(不需要改变)。所以我猜是派遣引起的。你的是延迟调用,发生在后沿。所以没什么问题。但这样前端交互效果就会很差,比如设置时间为1s,那么我点击提交按钮1s后才会真正触发。
这个不会吖,每一次操作其他控件全局的state都会变吖,也没见整个form有重刷对吧

你看下是不是你的事件绑定的不对,比如onclick或者onsearch 指定到方法定义,不要指定到方法执行。
小互哦

引用来自“小互哦”的评论

用的loadsh的debounce,出现一个问题,试了博主的debounce,问题依旧:dispatch会使debounce的前沿失效(环境:antd+dva)。而博主的这个插件的debounce默认是后沿。所以最后一个例子onSearch={debounce(1000, true, handleUserSearchChange)}会失效。猜测原因是派遣使状态改变,函数刷新重置,而后沿因为直接阻止,所以没发生派遣,所以有效。现在还不知道怎么解决,还请博主指点。

引用来自“王小明123”的评论

不是很懂你的描述,失效具体是是什么情况,我的控件交给了antd的管控,用了form的特性。所以我不需要自己维护控件的状态。

我只需要在控件发生onserch或者onclick的时候延迟调用后台服务即可,这时候确实是有state变化的,但是并没有阻断发生请求。
我现在的业务逻辑是提交表单,防止连续点击提交。所以用了debounce,就拿博客最后一个为例,如果改为前沿(第二个参数改为true),因为提交函数里面肯定有派遣(后台请求),这样debounce的防抖效果就会失效。只要有派遣发生,哪怕里面是空的,也会引起state刷新(不需要改变)。所以我猜是派遣引起的。你的是延迟调用,发生在后沿。所以没什么问题。但这样前端交互效果就会很差,比如设置时间为1s,那么我点击提交按钮1s后才会真正触发。
zimingforever
zimingforever 博主

引用来自“小互哦”的评论

用的loadsh的debounce,出现一个问题,试了博主的debounce,问题依旧:dispatch会使debounce的前沿失效(环境:antd+dva)。而博主的这个插件的debounce默认是后沿。所以最后一个例子onSearch={debounce(1000, true, handleUserSearchChange)}会失效。猜测原因是派遣使状态改变,函数刷新重置,而后沿因为直接阻止,所以没发生派遣,所以有效。现在还不知道怎么解决,还请博主指点。
不是很懂你的描述,失效具体是是什么情况,我的控件交给了antd的管控,用了form的特性。所以我不需要自己维护控件的状态。

我只需要在控件发生onserch或者onclick的时候延迟调用后台服务即可,这时候确实是有state变化的,但是并没有阻断发生请求。
小互哦
用的loadsh的debounce,出现一个问题,试了博主的debounce,问题依旧:dispatch会使debounce的前沿失效(环境:antd+dva)。而博主的这个插件的debounce默认是后沿。所以最后一个例子onSearch={debounce(1000, true, handleUserSearchChange)}会失效。猜测原因是派遣使状态改变,函数刷新重置,而后沿因为直接阻止,所以没发生派遣,所以有效。现在还不知道怎么解决,还请博主指点。
节流(throttle)与防抖(debounce)

频繁触发回调导致的大量计算会引发页面的抖动甚至卡顿。为了规避这种情况,我们需要一些手段来控制事件被触发的频率。就是在这样的背景下,throttle(事件节流)和 debounce(事件防抖)出现...

ShawnSun
08/17
0
0
浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异

Underscore.js是一个很精干的库,压缩后只有5.2KB。它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程。 本文仅探讨Underscore.js的两个函数方法 和 的原理、...

代码先生
2014/11/03
1K
4
浅谈 Underscorejs中 _.throttle 和 _.debounce 的差异和使用场景

通常的函数(或方法)调用过程分为三个部分:请求、执行和响应。(文中“请求”与“调用”同义,“响应”与“返回”同义,为了更好的表述,刻意采用请求和响应的说法。) 某些场景下,比如响...

山哥
2015/09/17
920
2
函数节流与防抖

函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。 用的比较多的地方就是resiz...

_Dot大师兄
2017/10/20
0
0
【进阶 6-4 期】深入浅出防抖函数 debounce

引言 上一节我们认识了节流函数 throttle,了解了它的定义、实现原理以及在 underscore 中的实现。这一小节会继续之前的篇幅聊聊防抖函数 debounce,结构是一样的,将分别介绍定义、实现原理...

木易杨说
06/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

高防CDN的出现是为了解决网站的哪些问题?

高防CDN是为了更好的服务网络而出现的,是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路,再反馈给用户,可以减轻用户使用过程的复杂程度。通过智能DNS解析,能让网站访问者连接到...

云漫网络Ruan
今天
12
0
聊聊Tomcat中的连接器(Connector)

上期回顾 上一篇文章《Tomcat在SpringBoot中是如何启动的》从main方法启动说起,窥探了SpringBoot是如何启动Tomcat的,在分析Tomcat中我们重点提到了,Tomcat主要包括2个组件,连接器(Conne...

木木匠
今天
9
0
OSChina 周一乱弹 —— 熟悉的味道,难道这就是恋爱的感觉

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoshiyue :好久没分享歌了分享张碧晨的单曲《今后我与自己流浪》 《今后我与自己流浪》- 张碧晨 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
2.4K
22
SpringBoot中 集成 redisTemplate 对 Redis 的操作(二)

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二) List 类型的操作 1、 向列表左侧添加数据 Long leftPush = redisTemplate.opsForList().leftPush("name", name); 2、 向列表右......

TcWong
今天
42
0
排序––快速排序(二)

根据排序––快速排序(一)的描述,现准备写一个快速排序的主体框架: 1、首先需要设置一个枢轴元素即setPivot(int i); 2、然后需要与枢轴元素进行比较即int comparePivot(int j); 3、最后...

FAT_mt
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部