Typescript封装防抖和节流函数

27 篇文章 1 订阅
24 篇文章 0 订阅
防抖函数

在规定时间内重复执行同一个函数,但是只生效一次函数的行为。比如由于网络延迟,用户在一定时间内会重复点击某一个按钮,然而不断的执行按钮上的事件。若该事件是网络请求,则会给服务器不断造成压力,这是我们不愿看到的。

节流函数

在规定时间内重复执行同一个函数,但是按照一定的时间段生效函数的行为。和防抖函数非常相似。例如在支付回调后我们要确认支付的状态,可以手动检查+自动检查的情况下,我们使用节流函数是一个不错的选择。

相对于使用JavaScript封装这两个函数主要区别在于this的指向问题。使用JavaScript封装我们大可以使用apply在函数中指向,但是对于Typescript中的this单独在函数中使用却是大大受限制的。所以在typescript中我们使用class来解决这一问题。

代码演示:

// 防抖(ts)
class Debounced {
  /**
   * @param func 需要包装的函数
   * @param delay 延迟时间,单位ms
   * @param immediate 是否默认执行一次(第一次不延迟)
   */
  public use = (func: Function, delay: number, immediate: boolean = false): Function => {
    let timer: number | undefined
    return ( ...args: any) => {
      if (immediate) {
        func.apply(this, args) // 确保引用函数的指向正确,并且函数的参数也不变
        immediate = false
        return
      }
      clearTimeout(timer)
      timer = setTimeout(() => {
        func.apply(this, args)
      }, delay)
    }
  }
}

// 节流(ts)
export class Throttle {
  private timer: number | undefined
  private stop: boolean = false
  private death: boolean = false
  /**
   * @param func 需要包装的函数
   * @param delay 延迟时间,单位ms
   * @param immediate 是否默认执行一次(第一次不延迟)
   */
  public use (func: Function, delay: number, immediate: boolean = false): Function {
    let flag = true
    const self = this
    return (...args: any) => {
      if (this.death) {
        func.apply(this, args)
        return
      }
      if (this.stop) {
        func.apply(this, args)
        return
      }
      if (immediate) {
        func.apply(this, args)
        immediate = false
        return
      }
      if (!flag) {
        return
      }
      flag = false
      self.timer = setTimeout(() => {
        func.apply(this, args)
        flag = true
      }, delay)
    }
  }

  // 销毁
  public destroy() {
    this.death = true
    this.stop = true
    if (!!this.timer) {
      clearTimeout(this.timer)
      this.timer = undefined
    }
  }
  // 开启
  public open() {
    if (!this.death) {
      this.stop = false
    }
  }
  // 关闭
  public close() {
    this.stop = true
  }
}

使用:

<template>
  <div id="debounced-test">
    <v-button @click="handelClickByDebounced">防抖</v-button>
    <v-button @click="handelClickByThrottle" type="success">节流</v-button>
    <v-button @click="changeStopThrottle(throttle.stop)" type="warning">
      {{ throttle.stop ? '开启' : '关闭' }}节流
    </v-button>
    <v-button @click="destroyThrottle" type="danger">销毁节流函数</v-button>
  </div>
</template>

<script lang="ts">
import { Debounced, Throttle } from '@/utils'
import { Vue, Component } from 'vue-property-decorator'

@Component
export default class DebouncedTest extends Vue {
  private count: number = 1
  private debouncedUse: Function = new Debounced().use(this.request, 1000)
  private throttle = new Throttle()
  private throttleUse: Function = this.throttle.use(this.request, 1000)

  private request(params: any) {
    console.log('this的指向', this);
    console.log('参数', params);
    console.log(this.count++)
  }
  // 防抖调用
  private handelClickByDebounced() {
    this.debouncedUse(123)
  }
  // 节流调用
  private handelClickByThrottle() {
    this.throttleUse('截流函数')
  }
  // 停止 | 开启节流函数
  private changeStopThrottle(action: boolean) {
    action ? this.throttle.open() : this.throttle.close()
  }
  // 销毁节流函数
  private destroyThrottle() {
    this.throttle.destroy()
  }
}
</script>

演示
演示

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
TypeScript(简称TS)是一种由微软开发的开源编程语言,它是JavaScript的一个超集,可以编译成纯JavaScript代码。在TS中,我们可以使用装饰器和泛型等特性来封装防抖节流函数防抖函数节流函数都是用于控制函数执行频率的方法,常用于优化性能和避免重复触发事件。 防抖函数的作用是在一定时间内,如果事件持续触发,则重新计时,直到事件停止触发后才执行函数。常见的应用场景是输入框搜索联想功能。 节流函数的作用是在一定时间内,无论事件触发多少次,只执行一次函数。常见的应用场景是滚动加载数据。 下面是一个使用TS封装防抖节流函数的示例: ```typescript // 防抖函数 function debounce(func: Function, delay: number): Function { let timer: number | null = null; return function (...args: any[]) { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { func.apply(this, args); }, delay); }; } // 节流函数 function throttle(func: Function, delay: number): Function { let timer: number | null = null; return function (...args: any[]) { if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } }; } ``` 使用示例: ```typescript function search(keyword: string) { // 模拟搜索功能 console.log(`Searching for ${keyword}`); } const debouncedSearch = debounce(search, 300); const throttledSearch = throttle(search, 300); debouncedSearch('apple'); debouncedSearch('banana'); debouncedSearch('cherry'); throttledSearch('apple'); throttledSearch('banana'); throttledSearch('cherry'); ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值