防抖和节流的应用场景和实现

栏目: JavaScript · 发布时间: 6年前

内容简介:防抖就是将一段时间内连续的多次触发转化为一次触发。一般可以使用在用户输入停止一段时间过后再去获取数据,而不是每次输入都去获取,如下图:原理很简单,主要是判断是否到达等待时间,如果没到达的话就继续加入任务队列等待执行。使用方法:
防抖和节流的应用场景和实现

防抖就是将一段时间内连续的多次触发转化为一次触发。

使用场景

一般可以使用在用户输入停止一段时间过后再去获取数据,而不是每次输入都去获取,如下图:

防抖和节流的应用场景和实现

实现代码

function debounce<Return>(
    fn: (...params: any[]) => Return, 
    wait: number, /** 等待时间 */
    immediate: boolean /** 是否立刻执行一次 */
  ): Executor<Return> {
    const now: () => number = Date.now.bind(Date);
    let lastTime: number = 0;
    let timer: number = null;
    let params: IArguments = null;
    let _this: Function | null = null;

    function later(): void {
      const nowTime: number = now();

      if (nowTime - lastTime < wait) {
        // 如果还不够等待时间则继续等待
        const remainTime = wait - (nowTime - lastTime);

        timer = setTimeout(later, remainTime);
      } else {
        // 已到等待时间,执行回调
        debouncer.result = fn.apply(_this, params);

        timer = null;
        _this = null;
        params = null;
      }
    }

    function execute(): (Return | null) {
      lastTime = now();
      _this = this;
      params = arguments;

      try {
        if (immediate && timer === null) {
          // 立刻执行一次
          debouncer.result = fn.apply(_this, params);
        }

        return debouncer.result;
      } finally {
        if (timer === null) {
          // 加入时间队列,等待执行
          timer = setTimeout(later, wait);
        }
      }
    }

    // 创建执行器
    const debouncer: Executor<Return> = {
      execute,
      result: null,
    };

    return debouncer;
  };
复制代码

原理很简单,主要是判断是否到达等待时间,如果没到达的话就继续加入任务队列等待执行。使用方法:

import utils from '../index';

const input = document.querySelector('input');
const executor = utils.fn.debounce(function(value) {
  console.log('fetch');
  
  return value;
}, 300);

let value = null;

input.addEventListener('input', function(e) {
  executor.execute(e.target.value);
  value = executor.result;
});
复制代码

返回一个执行器的原因是这样可以方便获取最后一次函数执行时返回的值。

节流

防抖和节流的应用场景和实现

节流顾名思义则是将减少一段时间内触发的频率。

使用场景

可以将一些事件降低触发频率。比如懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费资源;另外还有做商品预览图的放大镜效果时,不必每次鼠标移动都计算位置。

实现代码

throttle: function <Return>(
    fn: (...params: any[]) => Return,
    wait: number,
    {
      isExecuteAtStart = true,
      isExecuteAtEnd = true,
    }: ThrottleOptions = {
      isExecuteAtStart: true,
      isExecuteAtEnd: true,
    }
  ): Executor<Return> {
    let timer: number = null;
    let _this: Function = null;
    let params: IArguments = null;

    function execute(): (Return | null) {
      _this = this;
      params = arguments;

      if (isExecuteAtStart && timer === null) {
        // 如果需要开始的时候执行且没有计时器
        executor.result = fn.apply(_this, params);
        _this = null;
        params = null;
      }

      if (isExecuteAtEnd) {
        // 如果结束的时候需要执行
        if (timer === null) {
          timer = setTimeout(function () {
            executor.result = fn.apply(_this, params);
            _this = null;
            params = null;
            timer = null;
          }, wait);
        }
      }

      return executor.result;
    }

    const executor: Executor<Return> = {
      execute,
      result: null
    };

    return executor;
}
复制代码

最后

防抖和节流的目的都是为了减少不必要的计算,不浪费资源,只在适合的时候再进行触发计算。源码可以在 这个项目 里的fn模块看到,另外还有许多实用的功能,欢迎使用和学习。如果我的文章对你有些帮助的话,可以点个赞,谢谢~


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java语言程序设计

Java语言程序设计

(美) Y. Daniel Liang / 李娜 / 机械工业出版社 / 2011-6 / 79.00元

本书是Java语言的经典教材,畅销多年不衰。本书全面整合了Java的特性,采用“先讲基础”的教学方式,循序渐进地介绍了程序设计基础、面向对象程序设计、GUI程序设计等。另外,本书还全面且深入地覆盖了一些高级主题,包括算法和数据结构、并发、网络、国际化、高级GUI、数据库和Web程序设计等。 本书中文版由《Java语言程序设计 基础篇》和《Java语言程序设计 进阶篇》组成。基础篇对应原书的第......一起来看看 《Java语言程序设计》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具