mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 07:17:50 +00:00
Uses rAF by default for debounce/throtte unless `wait` is specified. (#3560)
This commit is contained in:
committed by
John-David Dalton
parent
fa73d46885
commit
d985dbffb8
50
debounce.js
50
debounce.js
@@ -1,15 +1,16 @@
|
||||
import isObject from './isObject.js'
|
||||
import root from './.internal/root.js'
|
||||
|
||||
/**
|
||||
* Creates a debounced function that delays invoking `func` until after `wait`
|
||||
* milliseconds have elapsed since the last time the debounced function was
|
||||
* invoked. The debounced function comes with a `cancel` method to cancel
|
||||
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
||||
* Provide `options` to indicate whether `func` should be invoked on the
|
||||
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
||||
* with the last arguments provided to the debounced function. Subsequent
|
||||
* calls to the debounced function return the result of the last `func`
|
||||
* invocation.
|
||||
* invoked, or until the next browser frame is drawn. The debounced function
|
||||
* comes with a `cancel` method to cancel delayed `func` invocations and a
|
||||
* `flush` method to immediately invoke them. Provide `options` to indicate
|
||||
* whether `func` should be invoked on the leading and/or trailing edge of the
|
||||
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
||||
* debounced function. Subsequent calls to the debounced function return the
|
||||
* result of the last `func` invocation.
|
||||
*
|
||||
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
||||
* invoked on the trailing edge of the timeout only if the debounced function
|
||||
@@ -18,13 +19,19 @@ import isObject from './isObject.js'
|
||||
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
||||
* until the next tick, similar to `setTimeout` with a timeout of `0`.
|
||||
*
|
||||
* If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
|
||||
* invocation will be deferred until the next frame is drawn (typically about
|
||||
* 16ms).
|
||||
*
|
||||
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||||
* for details over the differences between `debounce` and `throttle`.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @category Function
|
||||
* @param {Function} func The function to debounce.
|
||||
* @param {number} [wait=0] The number of milliseconds to delay.
|
||||
* @param {number} [wait=0]
|
||||
* The number of milliseconds to delay; if omitted, `requestAnimationFrame` is
|
||||
* used (if available).
|
||||
* @param {Object} [options={}] The options object.
|
||||
* @param {boolean} [options.leading=false]
|
||||
* Specify invoking on the leading edge of the timeout.
|
||||
@@ -68,6 +75,9 @@ function debounce(func, wait, options) {
|
||||
let maxing = false
|
||||
let trailing = true
|
||||
|
||||
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
|
||||
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
|
||||
|
||||
if (typeof func != 'function') {
|
||||
throw new TypeError('Expected a function')
|
||||
}
|
||||
@@ -89,11 +99,25 @@ function debounce(func, wait, options) {
|
||||
return result
|
||||
}
|
||||
|
||||
function startTimer(pendingFunc, wait) {
|
||||
if (useRAF) {
|
||||
return root.requestAnimationFrame(pendingFunc)
|
||||
}
|
||||
return setTimeout(pendingFunc, wait)
|
||||
}
|
||||
|
||||
function cancelTimer(id) {
|
||||
if (useRAF) {
|
||||
return root.cancelAnimationFrame(id)
|
||||
}
|
||||
clearTimeout(id)
|
||||
}
|
||||
|
||||
function leadingEdge(time) {
|
||||
// Reset any `maxWait` timer.
|
||||
lastInvokeTime = time
|
||||
// Start the timer for the trailing edge.
|
||||
timerId = setTimeout(timerExpired, wait)
|
||||
timerId = startTimer(timerExpired, wait)
|
||||
// Invoke the leading edge.
|
||||
return leading ? invokeFunc(time) : result
|
||||
}
|
||||
@@ -125,7 +149,7 @@ function debounce(func, wait, options) {
|
||||
return trailingEdge(time)
|
||||
}
|
||||
// Restart the timer.
|
||||
timerId = setTimeout(timerExpired, remainingWait(time))
|
||||
timerId = startTimer(timerExpired, remainingWait(time))
|
||||
}
|
||||
|
||||
function trailingEdge(time) {
|
||||
@@ -142,7 +166,7 @@ function debounce(func, wait, options) {
|
||||
|
||||
function cancel() {
|
||||
if (timerId !== undefined) {
|
||||
clearTimeout(timerId)
|
||||
cancelTimer(timerId)
|
||||
}
|
||||
lastInvokeTime = 0
|
||||
lastArgs = lastCallTime = lastThis = timerId = undefined
|
||||
@@ -170,12 +194,12 @@ function debounce(func, wait, options) {
|
||||
}
|
||||
if (maxing) {
|
||||
// Handle invocations in a tight loop.
|
||||
timerId = setTimeout(timerExpired, wait)
|
||||
timerId = startTimer(timerExpired, wait)
|
||||
return invokeFunc(lastCallTime)
|
||||
}
|
||||
}
|
||||
if (timerId === undefined) {
|
||||
timerId = setTimeout(timerExpired, wait)
|
||||
timerId = startTimer(timerExpired, wait)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
20
throttle.js
20
throttle.js
@@ -3,11 +3,11 @@ import isObject from './isObject.js'
|
||||
|
||||
/**
|
||||
* Creates a throttled function that only invokes `func` at most once per
|
||||
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
||||
* method to cancel delayed `func` invocations and a `flush` method to
|
||||
* immediately invoke them. Provide `options` to indicate whether `func`
|
||||
* should be invoked on the leading and/or trailing edge of the `wait`
|
||||
* timeout. The `func` is invoked with the last arguments provided to the
|
||||
* every `wait` milliseconds (or once per browser frame). The throttled function
|
||||
* comes with a `cancel` method to cancel delayed `func` invocations and a
|
||||
* `flush` method to immediately invoke them. Provide `options` to indicate
|
||||
* whether `func` should be invoked on the leading and/or trailing edge of the
|
||||
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
||||
* throttled function. Subsequent calls to the throttled function return the
|
||||
* result of the last `func` invocation.
|
||||
*
|
||||
@@ -16,7 +16,11 @@ import isObject from './isObject.js'
|
||||
* is invoked more than once during the `wait` timeout.
|
||||
*
|
||||
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
||||
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
||||
* until the next tick, similar to `setTimeout` with a timeout of `0`.
|
||||
*
|
||||
* If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
|
||||
* invocation will be deferred until the next frame is drawn (typically about
|
||||
* 16ms).
|
||||
*
|
||||
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||||
* for details over the differences between `throttle` and `debounce`.
|
||||
@@ -24,7 +28,9 @@ import isObject from './isObject.js'
|
||||
* @since 0.1.0
|
||||
* @category Function
|
||||
* @param {Function} func The function to throttle.
|
||||
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
|
||||
* @param {number} [wait=0]
|
||||
* The number of milliseconds to throttle invocations to; if omitted,
|
||||
* `requestAnimationFrame` is used (if available).
|
||||
* @param {Object} [options={}] The options object.
|
||||
* @param {boolean} [options.leading=true]
|
||||
* Specify invoking on the leading edge of the timeout.
|
||||
|
||||
Reference in New Issue
Block a user