UNPKG

foop

Version:

interfaces that describe their intentions.

137 lines (131 loc) 12.4 kB
var isObj = require('../is/obj') var isIn = require('../is/in') var noop = require('../util/noop') var toBoolean = require('../cast/toBoolean') var debounce = require('./debounce') /** * - Returns a function, that, when invoked, will only be triggered at most once * during a given window of time. Normally, the throttled function will run * as much as it can, without ever going more than once per `wait` duration; * but if you'd like to disable the execution on the leading edge, pass * `{leading: false}`. To disable execution on the trailing edge, ditto. * - 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 * throttled function. Subsequent calls to the throttled 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 throttled function * 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`. * * @since 5.0.0-beta.1 * * @param {Function} func The function to throttle. * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=true] * Specify invoking on the leading edge of the timeout. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @return {Function} Returns the new throttled function. * * @fork 0.1.0 * @category Function * * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/function.js#L172 sugar-throttle} * {@link https://github.com/lodash/lodash/blob/master/throttle.js lodash-throttle} * {@link https://css-tricks.com/debouncing-throttling-explained-examples/ debounce-vs-throttle-difference-explained} * @see {@link debounce-vs-throttle-difference-explained} * @see {@link lodash-throttle} * @see {@link sugar-throttle} * * @example * * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', throttle(updatePosition, 100)) * * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * const throttled = throttle(renewToken, 300000, { 'trailing': false }) * jQuery(element).on('click', throttled) * * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel) * */ module.exports = function throttle(func, wait, options) { var leading = true var trailing = true if (typeof func !== 'function') { func = noop // throw new TypeError('Expected a function') } if (isObj(options)) { leading = isIn(options, 'leading') ? toBoolean(options.leading) : leading trailing = isIn(options, 'trailing') ? toBoolean(options.trailing) : trailing } return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing, }) } // is underscore.js version // function(func, wait, options = {}) { // let timeout // let thisArg // let args // let result // let previous = 0 // // const later = function() { // previous = options.leading === false ? 0 : Date.now() // timeout = null // result = func.apply(thisArg, args) // if (!timeout) thisArg = args = null // } // // const throttled = function() { // const now = Date.now() // if (!previous && options.leading === false) previous = now // // const remaining = wait - (now - previous) // thisArg = this // args = arguments // // if (remaining <= 0 || remaining > wait) { // if (timeout) { // clearTimeout(timeout) // timeout = null // } // // previous = now // result = func.apply(thisArg, args) // // if (!timeout) thisArg = args = null // } // else if (!timeout && options.trailing !== false) { // timeout = setTimeout(later, remaining) // } // return result // } // // throttled.cancel = function() { // clearTimeout(timeout) // previous = 0 // timeout = thisArg = args = null // } // // return throttled // } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyb3R0bGUuanMiLCJzb3VyY2VzIjpbInRocm90dGxlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGlzT2JqID0gcmVxdWlyZSgnLi4vaXMvb2JqJylcbmNvbnN0IGlzSW4gPSByZXF1aXJlKCcuLi9pcy9pbicpXG5jb25zdCBub29wID0gcmVxdWlyZSgnLi4vdXRpbC9ub29wJylcbmNvbnN0IHRvQm9vbGVhbiA9IHJlcXVpcmUoJy4uL2Nhc3QvdG9Cb29sZWFuJylcbmNvbnN0IGRlYm91bmNlID0gcmVxdWlyZSgnLi9kZWJvdW5jZScpXG5cbi8qKlxuICogLSBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIHdoZW4gaW52b2tlZCwgd2lsbCBvbmx5IGJlIHRyaWdnZXJlZCBhdCBtb3N0IG9uY2VcbiAqIGR1cmluZyBhIGdpdmVuIHdpbmRvdyBvZiB0aW1lLiBOb3JtYWxseSwgdGhlIHRocm90dGxlZCBmdW5jdGlvbiB3aWxsIHJ1blxuICogYXMgbXVjaCBhcyBpdCBjYW4sIHdpdGhvdXQgZXZlciBnb2luZyBtb3JlIHRoYW4gb25jZSBwZXIgYHdhaXRgIGR1cmF0aW9uO1xuICogYnV0IGlmIHlvdSdkIGxpa2UgdG8gZGlzYWJsZSB0aGUgZXhlY3V0aW9uIG9uIHRoZSBsZWFkaW5nIGVkZ2UsIHBhc3NcbiAqIGB7bGVhZGluZzogZmFsc2V9YC4gVG8gZGlzYWJsZSBleGVjdXRpb24gb24gdGhlIHRyYWlsaW5nIGVkZ2UsIGRpdHRvLlxuICogLSBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyXG4gKiBldmVyeSBgd2FpdGAgbWlsbGlzZWNvbmRzLiBUaGUgdGhyb3R0bGVkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYFxuICogbWV0aG9kIHRvIGNhbmNlbCBkZWxheWVkIGBmdW5jYCBpbnZvY2F0aW9ucyBhbmQgYSBgZmx1c2hgIG1ldGhvZCB0b1xuICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgXG4gKiBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGUgbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgXG4gKiB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWQgd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlXG4gKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gKiByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgIGludm9jYXRpb24uXG4gKlxuICogQE5PVEUgSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIHRocm90dGxlZCBmdW5jdGlvblxuICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZFxuICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICpcbiAqIEBzaW5jZSA1LjAuMC1iZXRhLjFcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB0aHJvdHRsZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sZWFkaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHRocm90dGxlZCBmdW5jdGlvbi5cbiAqXG4gKiBAZm9yayAwLjEuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKlxuICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmRyZXdwbHVtbWVyL1N1Z2FyL2Jsb2IvbWFzdGVyL2xpYi9mdW5jdGlvbi5qcyNMMTcyIHN1Z2FyLXRocm90dGxlfVxuICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2Rhc2gvbG9kYXNoL2Jsb2IvbWFzdGVyL3Rocm90dGxlLmpzIGxvZGFzaC10aHJvdHRsZX1cbiAqIHtAbGluayBodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvIGRlYm91bmNlLXZzLXRocm90dGxlLWRpZmZlcmVuY2UtZXhwbGFpbmVkfVxuICogQHNlZSB7QGxpbmsgZGVib3VuY2UtdnMtdGhyb3R0bGUtZGlmZmVyZW5jZS1leHBsYWluZWR9XG4gKiBAc2VlIHtAbGluayBsb2Rhc2gtdGhyb3R0bGV9XG4gKiBAc2VlIHtAbGluayBzdWdhci10aHJvdHRsZX1cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgICAvLyBBdm9pZCBleGNlc3NpdmVseSB1cGRhdGluZyB0aGUgcG9zaXRpb24gd2hpbGUgc2Nyb2xsaW5nLlxuICogICAgIGpRdWVyeSh3aW5kb3cpLm9uKCdzY3JvbGwnLCB0aHJvdHRsZSh1cGRhdGVQb3NpdGlvbiwgMTAwKSlcbiAqXG4gKiAgICAgLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuXG4gKiAgICAgY29uc3QgdGhyb3R0bGVkID0gdGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pXG4gKiAgICAgalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHRocm90dGxlZClcbiAqXG4gKiAgICAgLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAqICAgICBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKVxuICpcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIGxldCBsZWFkaW5nID0gdHJ1ZVxuICBsZXQgdHJhaWxpbmcgPSB0cnVlXG5cbiAgaWYgKHR5cGVvZiBmdW5jICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgZnVuYyA9IG5vb3BcbiAgICAvLyB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBhIGZ1bmN0aW9uJylcbiAgfVxuICBpZiAoaXNPYmoob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gaXNJbihvcHRpb25zLCAnbGVhZGluZycpXG4gICAgICA/IHRvQm9vbGVhbihvcHRpb25zLmxlYWRpbmcpXG4gICAgICA6IGxlYWRpbmdcblxuICAgIHRyYWlsaW5nID0gaXNJbihvcHRpb25zLCAndHJhaWxpbmcnKVxuICAgICAgPyB0b0Jvb2xlYW4ob3B0aW9ucy50cmFpbGluZylcbiAgICAgIDogdHJhaWxpbmdcbiAgfVxuXG4gIHJldHVybiBkZWJvdW5jZShmdW5jLCB3YWl0LCB7XG4gICAgJ2xlYWRpbmcnOiBsZWFkaW5nLFxuICAgICdtYXhXYWl0Jzogd2FpdCxcbiAgICAndHJhaWxpbmcnOiB0cmFpbGluZyxcbiAgfSlcbn1cblxuLy8gaXMgdW5kZXJzY29yZS5qcyB2ZXJzaW9uXG4vLyBmdW5jdGlvbihmdW5jLCB3YWl0LCBvcHRpb25zID0ge30pIHtcbi8vICAgbGV0IHRpbWVvdXRcbi8vICAgbGV0IHRoaXNBcmdcbi8vICAgbGV0IGFyZ3Ncbi8vICAgbGV0IHJlc3VsdFxuLy8gICBsZXQgcHJldmlvdXMgPSAwXG4vL1xuLy8gICBjb25zdCBsYXRlciA9IGZ1bmN0aW9uKCkge1xuLy8gICAgIHByZXZpb3VzID0gb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSA/IDAgOiBEYXRlLm5vdygpXG4vLyAgICAgdGltZW91dCA9IG51bGxcbi8vICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpXG4vLyAgICAgaWYgKCF0aW1lb3V0KSB0aGlzQXJnID0gYXJncyA9IG51bGxcbi8vICAgfVxuLy9cbi8vICAgY29uc3QgdGhyb3R0bGVkID0gZnVuY3Rpb24oKSB7XG4vLyAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuLy8gICAgIGlmICghcHJldmlvdXMgJiYgb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSkgcHJldmlvdXMgPSBub3dcbi8vXG4vLyAgICAgY29uc3QgcmVtYWluaW5nID0gd2FpdCAtIChub3cgLSBwcmV2aW91cylcbi8vICAgICB0aGlzQXJnID0gdGhpc1xuLy8gICAgIGFyZ3MgPSBhcmd1bWVudHNcbi8vXG4vLyAgICAgaWYgKHJlbWFpbmluZyA8PSAwIHx8IHJlbWFpbmluZyA+IHdhaXQpIHtcbi8vICAgICAgIGlmICh0aW1lb3V0KSB7XG4vLyAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KVxuLy8gICAgICAgICB0aW1lb3V0ID0gbnVsbFxuLy8gICAgICAgfVxuLy9cbi8vICAgICAgIHByZXZpb3VzID0gbm93XG4vLyAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpXG4vL1xuLy8gICAgICAgaWYgKCF0aW1lb3V0KSB0aGlzQXJnID0gYXJncyA9IG51bGxcbi8vICAgICB9XG4vLyAgICAgZWxzZSBpZiAoIXRpbWVvdXQgJiYgb3B0aW9ucy50cmFpbGluZyAhPT0gZmFsc2UpIHtcbi8vICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCByZW1haW5pbmcpXG4vLyAgICAgfVxuLy8gICAgIHJldHVybiByZXN1bHRcbi8vICAgfVxuLy9cbi8vICAgdGhyb3R0bGVkLmNhbmNlbCA9IGZ1bmN0aW9uKCkge1xuLy8gICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KVxuLy8gICAgIHByZXZpb3VzID0gMFxuLy8gICAgIHRpbWVvdXQgPSB0aGlzQXJnID0gYXJncyA9IG51bGxcbi8vICAgfVxuLy9cbi8vICAgcmV0dXJuIHRocm90dGxlZFxuLy8gfVxuIl0sIm5hbWVzIjpbImNvbnN0IiwibGV0Il0sIm1hcHBpbmdzIjoiQUFBQUEsR0FBSyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQ2xDQSxHQUFLLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFDaENBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztBQUNwQ0EsR0FBSyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUM7QUFDOUNBLEdBQUssQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBEdEMsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtFQUN0REMsR0FBRyxDQUFDLE9BQU8sR0FBRyxJQUFJO0VBQ2xCQSxHQUFHLENBQUMsUUFBUSxHQUFHLElBQUk7O0VBRW5CLElBQUksT0FBTyxJQUFJLEtBQUssVUFBVSxFQUFFO0lBQzlCLElBQUksR0FBRyxJQUFJOztHQUVaO0VBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDbEIsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDO1FBQzlCLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQzFCLE9BQU87O0lBRVgsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDO1FBQ2hDLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQzNCLFFBQVE7R0FDYjs7RUFFRCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFO0lBQzFCLFNBQVMsRUFBRSxPQUFPO0lBQ2xCLFNBQVMsRUFBRSxJQUFJO0lBQ2YsVUFBVSxFQUFFLFFBQVE7R0FDckIsQ0FBQztDQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==