mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-07 01:57: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 isObject from './isObject.js'
|
||||||
|
import root from './.internal/root.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a debounced function that delays invoking `func` until after `wait`
|
* Creates a debounced function that delays invoking `func` until after `wait`
|
||||||
* milliseconds have elapsed since the last time the debounced function was
|
* milliseconds have elapsed since the last time the debounced function was
|
||||||
* invoked. The debounced function comes with a `cancel` method to cancel
|
* invoked, or until the next browser frame is drawn. The debounced function
|
||||||
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
* comes with a `cancel` method to cancel delayed `func` invocations and a
|
||||||
* Provide `options` to indicate whether `func` should be invoked on the
|
* `flush` method to immediately invoke them. Provide `options` to indicate
|
||||||
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
* whether `func` should be invoked on the leading and/or trailing edge of the
|
||||||
* with the last arguments provided to the debounced function. Subsequent
|
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
||||||
* calls to the debounced function return the result of the last `func`
|
* debounced function. Subsequent calls to the debounced function return the
|
||||||
* invocation.
|
* result of the last `func` invocation.
|
||||||
*
|
*
|
||||||
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
||||||
* invoked on the trailing edge of the timeout only if the debounced function
|
* 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
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
||||||
* until 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/)
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||||||
* for details over the differences between `debounce` and `throttle`.
|
* for details over the differences between `debounce` and `throttle`.
|
||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
* @category Function
|
* @category Function
|
||||||
* @param {Function} func The function to debounce.
|
* @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 {Object} [options={}] The options object.
|
||||||
* @param {boolean} [options.leading=false]
|
* @param {boolean} [options.leading=false]
|
||||||
* Specify invoking on the leading edge of the timeout.
|
* Specify invoking on the leading edge of the timeout.
|
||||||
@@ -68,6 +75,9 @@ function debounce(func, wait, options) {
|
|||||||
let maxing = false
|
let maxing = false
|
||||||
let trailing = true
|
let trailing = true
|
||||||
|
|
||||||
|
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
|
||||||
|
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
|
||||||
|
|
||||||
if (typeof func != 'function') {
|
if (typeof func != 'function') {
|
||||||
throw new TypeError('Expected a function')
|
throw new TypeError('Expected a function')
|
||||||
}
|
}
|
||||||
@@ -89,11 +99,25 @@ function debounce(func, wait, options) {
|
|||||||
return result
|
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) {
|
function leadingEdge(time) {
|
||||||
// Reset any `maxWait` timer.
|
// Reset any `maxWait` timer.
|
||||||
lastInvokeTime = time
|
lastInvokeTime = time
|
||||||
// Start the timer for the trailing edge.
|
// Start the timer for the trailing edge.
|
||||||
timerId = setTimeout(timerExpired, wait)
|
timerId = startTimer(timerExpired, wait)
|
||||||
// Invoke the leading edge.
|
// Invoke the leading edge.
|
||||||
return leading ? invokeFunc(time) : result
|
return leading ? invokeFunc(time) : result
|
||||||
}
|
}
|
||||||
@@ -125,7 +149,7 @@ function debounce(func, wait, options) {
|
|||||||
return trailingEdge(time)
|
return trailingEdge(time)
|
||||||
}
|
}
|
||||||
// Restart the timer.
|
// Restart the timer.
|
||||||
timerId = setTimeout(timerExpired, remainingWait(time))
|
timerId = startTimer(timerExpired, remainingWait(time))
|
||||||
}
|
}
|
||||||
|
|
||||||
function trailingEdge(time) {
|
function trailingEdge(time) {
|
||||||
@@ -142,7 +166,7 @@ function debounce(func, wait, options) {
|
|||||||
|
|
||||||
function cancel() {
|
function cancel() {
|
||||||
if (timerId !== undefined) {
|
if (timerId !== undefined) {
|
||||||
clearTimeout(timerId)
|
cancelTimer(timerId)
|
||||||
}
|
}
|
||||||
lastInvokeTime = 0
|
lastInvokeTime = 0
|
||||||
lastArgs = lastCallTime = lastThis = timerId = undefined
|
lastArgs = lastCallTime = lastThis = timerId = undefined
|
||||||
@@ -170,12 +194,12 @@ function debounce(func, wait, options) {
|
|||||||
}
|
}
|
||||||
if (maxing) {
|
if (maxing) {
|
||||||
// Handle invocations in a tight loop.
|
// Handle invocations in a tight loop.
|
||||||
timerId = setTimeout(timerExpired, wait)
|
timerId = startTimer(timerExpired, wait)
|
||||||
return invokeFunc(lastCallTime)
|
return invokeFunc(lastCallTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timerId === undefined) {
|
if (timerId === undefined) {
|
||||||
timerId = setTimeout(timerExpired, wait)
|
timerId = startTimer(timerExpired, wait)
|
||||||
}
|
}
|
||||||
return result
|
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
|
* Creates a throttled function that only invokes `func` at most once per
|
||||||
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
* every `wait` milliseconds (or once per browser frame). The throttled function
|
||||||
* method to cancel delayed `func` invocations and a `flush` method to
|
* comes with a `cancel` method to cancel delayed `func` invocations and a
|
||||||
* immediately invoke them. Provide `options` to indicate whether `func`
|
* `flush` method to immediately invoke them. Provide `options` to indicate
|
||||||
* should be invoked on the leading and/or trailing edge of the `wait`
|
* whether `func` should be invoked on the leading and/or trailing edge of the
|
||||||
* timeout. The `func` is invoked with the last arguments provided to the
|
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
||||||
* throttled function. Subsequent calls to the throttled function return the
|
* throttled function. Subsequent calls to the throttled function return the
|
||||||
* result of the last `func` invocation.
|
* result of the last `func` invocation.
|
||||||
*
|
*
|
||||||
@@ -16,7 +16,11 @@ import isObject from './isObject.js'
|
|||||||
* is invoked more than once during the `wait` timeout.
|
* is invoked more than once during the `wait` timeout.
|
||||||
*
|
*
|
||||||
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
* 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/)
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||||||
* for details over the differences between `throttle` and `debounce`.
|
* for details over the differences between `throttle` and `debounce`.
|
||||||
@@ -24,7 +28,9 @@ import isObject from './isObject.js'
|
|||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
* @category Function
|
* @category Function
|
||||||
* @param {Function} func The function to throttle.
|
* @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 {Object} [options={}] The options object.
|
||||||
* @param {boolean} [options.leading=true]
|
* @param {boolean} [options.leading=true]
|
||||||
* Specify invoking on the leading edge of the timeout.
|
* Specify invoking on the leading edge of the timeout.
|
||||||
|
|||||||
Reference in New Issue
Block a user