Skip to content

useThrottleFnWithLock/useDebounceFnWithLock

结合 useLockFn 和 useThrottleFn/useDebounceFn 的特性,在给函数加了竞态锁的同时加上节流/防抖,需要异步函数执行结束并且节流/防抖时间已过才可以再次执行函数

换句话说,useThrottleFnWithLock/useDebounceFnWithLock 会选择函数的实际执行时间节流/防抖时间较大的时长作为实际的节流/防抖时间

js
import {useThrottleFnWithLock} from '@ifanr/uni-mp'

function mockRequest(ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}

// 节流函数执行需要花费 5s,即使节流时间已过,也不允许再次执行,需等待函数执行完毕后才可再次执行
const {run: throttleFn1} = useThrottleFnWithLock(() => mockRequest(5000), 3000)

// 节流函数执行时间小于节流时间,需要等待节流时间过后才可再次执行
const {run: throttleFn2} = useThrottleFnWithLock(() => mockRequest(3000), 5000)
import {useThrottleFnWithLock} from '@ifanr/uni-mp'

function mockRequest(ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}

// 节流函数执行需要花费 5s,即使节流时间已过,也不允许再次执行,需等待函数执行完毕后才可再次执行
const {run: throttleFn1} = useThrottleFnWithLock(() => mockRequest(5000), 3000)

// 节流函数执行时间小于节流时间,需要等待节流时间过后才可再次执行
const {run: throttleFn2} = useThrottleFnWithLock(() => mockRequest(3000), 5000)

适用场景

  • 给函数加了 3s 的节流,但是由于上一个请求还没有响应,会导致重复的请求发出。多了一层 lock 就可以实现在请求没有响应之前即使节流已经失效,也不会发出新的请求。一般用于 POST/PUT/DELETE 请求,如表单提交或者秒杀场景

  • 限制按钮在规定时间内只能点击一次,在该时间段内重复点击需要给用户提示

vue
<script setup>
import {useThrottleFnWithLock, message} from '@ifanrx/uni-mp'

function mockRequest(ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}

// 限制用户在一分钟内只能点击一次,同时确保下一次点击时上一个请求已经得到响应
const {run: submit, pending} = useThrottleFnWithLock(() => mockRequest(3000), 60 * 1000)

function onClick() {
  // pending 是结合了 throttleFn.pending 和 lockFn.locked 来实现,具体查看源码
  if (pending()) {
    message.showToast('请不要点击太快')
    return
  }

  await submit()
}
</script>

<template>
  <button @click="onClick">领取票券</button>
</template>
<script setup>
import {useThrottleFnWithLock, message} from '@ifanrx/uni-mp'

function mockRequest(ms) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}

// 限制用户在一分钟内只能点击一次,同时确保下一次点击时上一个请求已经得到响应
const {run: submit, pending} = useThrottleFnWithLock(() => mockRequest(3000), 60 * 1000)

function onClick() {
  // pending 是结合了 throttleFn.pending 和 lockFn.locked 来实现,具体查看源码
  if (pending()) {
    message.showToast('请不要点击太快')
    return
  }

  await submit()
}
</script>

<template>
  <button @click="onClick">领取票券</button>
</template>

相关文档