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

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

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

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

使用场景

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

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

实现代码

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模块看到,另外还有许多实用的功能,欢迎使用和学习。如果我的文章对你有些帮助的话,可以点个赞,谢谢~


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

查看所有标签

猜你喜欢:

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

可伸缩架构

可伸缩架构

【美】Lee Atchison / 张若飞、张现双 / 电子工业出版社 / 2017-7 / 65

随着互联网的发展越来越成熟,流量和数据量飞速增长,许多公司的关键应用程序都面临着伸缩性的问题,系统变得越来越复杂和脆弱,从而导致风险上升、可用性降低。《可伸缩架构:面向增长应用的高可用》是一本实践指南,让IT、DevOps和系统稳定性管理员能够了解到,如何避免应用程序在发展过程中变得缓慢、数据不一致或者彻底不可用等问题。规模增长并不只意味着处理更多的用户,还包括管理更多的风险和保证系统的可用性。作......一起来看看 《可伸缩架构》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具