前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数防抖和函数节流的简单实现和探讨

函数防抖和函数节流的简单实现和探讨

作者头像
flytam
发布2020-01-14 17:06:31
5520
发布2020-01-14 17:06:31
举报

函数防抖和函数节流

函数防抖(debounce)
  • 通俗的说作用就是防止某个函数执行过于频繁。也就是说就是让某个函数在上一次执行后,满足等待某个时间内不再触发此函数后再执行,而在这个等待时间内再次触发此函数,等待时间会重新计算。
  • 应用场景
    • 例如某个resize事件,我们想resize触发时去执行某个函数,但是resize是在窗口不停拖动会不断触发的,而很多时候我们不必拖动过程中不停执行那个函数这样很消耗性能也没有必要。所以就需要一个防抖,设定一个时间间隔让它一定时间间隔后执行
    • 防止提交表单按钮被多次点击发送多次请求(这个需要对比上面做点小修改)
  • 实现
代码语言:javascript
复制
//没有考虑上下文和错误处理版本的防抖函数就如下而
/**
 * 
 * @param {function} func 执行的函数
 * @param {number} time 防抖的时间
 */
  const debounce = (func,time = 500) =>{
    let timeout;
    return () => {
        if (timeout) clearTimeout(timeout);
        setTimeout(func,time);
    }
}
const eventdo = debounce(some,1000);
element.onscroll = eventdo;

上面有个问题就是如果再场景2那种情况,用户提交数据请求是发不出去的。而且不停点击,请求就一直不发,这显然是不科学的,我们就要改进这个函数了。

代码语言:javascript
复制
/**
 *
 * @param {function} func 执行的函数
 * @param {boll} immediate 是否马上执行一遍
 * @param {number} time 防抖的时间
 */
 //简易版本防抖函数的实现
const debounce = (func, immediate = false, time = 500) => {
    let timeout,
        hasImmediate = immediate;
    let later = (args) => {
        timeout = null; //这里设为null是再马上需要调用一次那种情况用的。就是说如果执行了,就表示重新再来
        if (args) func(...args);
    }
    return (...args) => {
        if (timeout) 
            clearTimeout(timeout);
        if (immediate) {
            const callNow = !timeout; //马上执行一遍
            if (callNow) 
                func(...args);
            setTimeout(later,time);//防止疯狂点击,因为我们没有传参数给later,所以later函数的args是undefined,它里面也不会执行的

        } else {
            setTimeout(() =>later(args),time);

        }
    }
}

我们可见如果传入了immediate参数,这个防抖函数会马上执行一遍,在之后的time时间内,都不能点击,如果疯狂点击这个时间也不断延长。这样就实现了一个基本的防抖函数了。

函数节流(throttle)
  • 函数节流就是说一个固定的时间内,某个函数只会被执行一遍
代码语言:javascript
复制
/**
 * 
 * @param {function} func 执行的函数
 * @param {number} wait  节流时间
 */
 //简易版本节流函数的实现
const throttle = (func,wait) =>{
    let previous = 0;//记录函数上一次执行的时间
    return (...arg) =>{
        let now = Date.now();
        if (!previous) previous = now;
        let remaining = wait - (now - previous);//剩余时间
        if (remaining < 0 || remaining > wait){
            //超过了节流时间
            //执行函数
            func(...arg);
            previous = now;
        }
    }
}

函数节流和函数防抖都是利用了setTimeout的特性进行操作的,在优化函数频繁调用中十分有用。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数防抖和函数节流
    • 函数防抖(debounce)
      • 函数节流(throttle)
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档