Skip to content

Commit

Permalink
feat(throttleFilter): add leading option (vitest-dev#771)
Browse files Browse the repository at this point in the history
  • Loading branch information
FRSgit committed Sep 25, 2021
1 parent 96a14f8 commit c0078fb
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/shared/useDebounceFn/index.md
Expand Up @@ -17,7 +17,7 @@ const debouncedFn = useDebounceFn(() => {
// do something
}, 1000)

document.addEventLisenter('resize', debouncedFn)
document.addEventListener('resize', debouncedFn)
```

## Related Functions
Expand Down
4 changes: 3 additions & 1 deletion packages/shared/useThrottle/demo.vue
Expand Up @@ -3,8 +3,9 @@ import { ref, watch } from 'vue-demi'
import { useThrottle } from '.'
const trailing = ref(true)
const leading = ref(false)
const input = ref('')
const throttled = useThrottle(input, 1000, trailing.value)
const throttled = useThrottle(input, 1000, trailing.value, leading.value)
const updated = ref(0)
watch(throttled, () => {
Expand All @@ -20,5 +21,6 @@ watch(throttled, () => {
<p>Throttled: {{ throttled }}</p>
<p>Times Updated: {{ updated }}</p>
<p>Trailing: {{ trailing }}</p>
<p>Leading: {{ leading }}</p>
</div>
</template>
10 changes: 10 additions & 0 deletions packages/shared/useThrottle/index.md
Expand Up @@ -26,6 +26,16 @@ const input = ref('')
const throttled = useThrottle(input, 1000, false)
```

### Leading

Allows the callback to be invoked immediately (on the leading edge of the `ms` timeout). If you don't want this begavior, set 4rd param `false` (it's `true` by default):

```js
import { useThrottle } from '@vueuse/core'

const input = ref('')
const throttled = useThrottle(input, 1000, undefined, false)
```

## Related Functions

Expand Down
5 changes: 3 additions & 2 deletions packages/shared/useThrottle/index.ts
Expand Up @@ -8,16 +8,17 @@ import { useThrottleFn } from '../useThrottleFn'
* @param value Ref value to be watched with throttle effect
* @param delay A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.
* @param [trailing=true] if true, update the value again after the delay time is up
* @param [leading=true] if true, update the value on the leading edge of the ms timeout
*/
export function useThrottle<T>(value: Ref<T>, delay = 200, trailing = true) {
export function useThrottle<T>(value: Ref<T>, delay = 200, trailing = true, leading = true) {
if (delay <= 0)
return value

const throttled: Ref<T> = ref(value.value as T) as Ref<T>

const updater = useThrottleFn(() => {
throttled.value = value.value
}, delay, trailing)
}, delay, trailing, leading)

watch(value, () => updater())

Expand Down
2 changes: 1 addition & 1 deletion packages/shared/useThrottleFn/index.md
Expand Up @@ -17,7 +17,7 @@ const throttledFn = useThrottleFn(() => {
// do something, it will be called at most 1 time per second
}, 1000)

document.addEventLisenter('resize', throttledFn)
document.addEventListener('resize', throttledFn)
```

## Related Functions
Expand Down
6 changes: 4 additions & 2 deletions packages/shared/useThrottleFn/index.ts
Expand Up @@ -10,11 +10,13 @@ import { createFilterWrapper, FunctionArgs, throttleFilter, MaybeRef } from '../
*
* @param [trailing=true] if true, call fn again after the time is up
*
* @param [leading=true] if true, call fn on the leading edge of the ms timeout
*
* @return A new, throttled, function.
*/
export function useThrottleFn<T extends FunctionArgs>(fn: T, ms: MaybeRef<number> = 200, trailing = true): T {
export function useThrottleFn<T extends FunctionArgs>(fn: T, ms: MaybeRef<number> = 200, trailing = true, leading = true): T {
return createFilterWrapper(
throttleFilter(ms, trailing),
throttleFilter(ms, trailing, leading),
fn,
)
}
10 changes: 8 additions & 2 deletions packages/shared/utils/filters.ts
Expand Up @@ -66,10 +66,12 @@ export function debounceFilter(ms: MaybeRef<number>) {
*
* @param ms
* @param [trailing=true]
* @param [leading=true]
*/
export function throttleFilter(ms: MaybeRef<number>, trailing = true) {
export function throttleFilter(ms: MaybeRef<number>, trailing = true, leading = true) {
let lastExec = 0
let timer: ReturnType<typeof setTimeout> | undefined
let preventLeading = !leading

const clear = () => {
if (timer) {
Expand All @@ -91,15 +93,19 @@ export function throttleFilter(ms: MaybeRef<number>, trailing = true) {

if (elapsed > duration) {
lastExec = Date.now()
invoke()
if (preventLeading) preventLeading = false
else invoke()
}
else if (trailing) {
timer = setTimeout(() => {
lastExec = Date.now()
if (!leading) preventLeading = true
clear()
invoke()
}, duration)
}

if (!leading && !timer) timer = setTimeout(() => preventLeading = true, duration)
}

return filter
Expand Down

0 comments on commit c0078fb

Please sign in to comment.