| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- import {arrayReduce} from './array';
- /**
- * Checks if given variable is function.
- *
- * @param {*} func Variable to check.
- * @returns {Boolean}
- */
- export function isFunction(func) {
- return typeof func === 'function';
- }
- /**
- * Creates throttle function that enforces a maximum number of times a function (`func`) can be called over time (`wait`).
- *
- * @param {Function} func Function to invoke.
- * @param {Number} wait Delay in miliseconds.
- * @returns {Function}
- */
- export function throttle(func, wait = 200) {
- let lastCalled = 0;
- let result = {
- lastCallThrottled: true
- };
- let lastTimer = null;
- function _throttle() {
- const args = arguments;
- let stamp = Date.now();
- let needCall = false;
- result.lastCallThrottled = true;
- if (!lastCalled) {
- lastCalled = stamp;
- needCall = true;
- }
- let remaining = wait - (stamp - lastCalled);
- if (needCall) {
- result.lastCallThrottled = false;
- func.apply(this, args);
- } else {
- if (lastTimer) {
- clearTimeout(lastTimer);
- }
- lastTimer = setTimeout(() => {
- result.lastCallThrottled = false;
- func.apply(this, args);
- lastCalled = 0;
- lastTimer = void 0;
- }, remaining);
- }
- return result;
- }
- return _throttle;
- }
- /**
- * Creates throttle function that enforces a maximum number of times a function (`func`) can be called over
- * time (`wait`) after specified hits.
- *
- * @param {Function} func Function to invoke.
- * @param {Number} wait Delay in miliseconds.
- * @param {Number} hits Number of hits after throttling will be applied.
- * @returns {Function}
- */
- export function throttleAfterHits(func, wait = 200, hits = 10) {
- const funcThrottle = throttle(func, wait);
- let remainHits = hits;
- function _clearHits() {
- remainHits = hits;
- }
- function _throttleAfterHits() {
- if (remainHits) {
- remainHits--;
- return func.apply(this, arguments);
- }
- return funcThrottle.apply(this, arguments);
- }
- _throttleAfterHits.clearHits = _clearHits;
- return _throttleAfterHits;
- }
- /**
- * Creates debounce function that enforces a function (`func`) not be called again until a certain amount of time (`wait`)
- * has passed without it being called.
- *
- * @param {Function} func Function to invoke.
- * @param {Number} wait Delay in milliseconds.
- * @returns {Function}
- */
- export function debounce(func, wait = 200) {
- let lastTimer = null;
- let result;
- function _debounce() {
- const args = arguments;
- if (lastTimer) {
- clearTimeout(lastTimer);
- }
- lastTimer = setTimeout(() => {
- result = func.apply(this, args);
- }, wait);
- return result;
- }
- return _debounce;
- }
- /**
- * Creates the function that returns the result of calling the given functions. Result of the first function is passed to
- * the second as an argument and so on. Only first function in the chain can handle multiple arguments.
- *
- * @param {Function} functions Functions to compose.
- * @returns {Function}
- */
- export function pipe(...functions) {
- const [firstFunc, ...restFunc] = functions;
- return function _pipe() {
- return arrayReduce(restFunc, (acc, fn) => fn(acc), firstFunc.apply(this, arguments));
- };
- }
- /**
- * Creates the function that returns the function with cached arguments.
- *
- * @param {Function} func Function to partialization.
- * @param {Array} params Function arguments to cache.
- * @returns {Function}
- */
- export function partial(func, ...params) {
- return function _partial(...restParams) {
- return func.apply(this, params.concat(restParams));
- };
- }
- /**
- * Creates the functions that returns the function with cached arguments. If count if passed arguments will be matched
- * to the arguments defined in `func` then function will be invoked.
- * Arguments are added to the stack in direction from the left to the right.
- *
- * @example
- * ```
- * var replace = curry(function(find, replace, string) {
- * return string.replace(find, replace);
- * });
- *
- * // returns function with bounded first argument
- * var replace = replace('foo')
- *
- * // returns replaced string - all arguments was passed so function was invoked
- * replace('bar', 'Some test with foo...');
- *
- * ```
- *
- * @param {Function} func Function to currying.
- * @returns {Function}
- */
- export function curry(func) {
- const argsLength = func.length;
- function given(argsSoFar) {
- return function _curry(...params) {
- const passedArgsSoFar = argsSoFar.concat(params);
- let result;
- if (passedArgsSoFar.length >= argsLength) {
- result = func.apply(this, passedArgsSoFar);
- } else {
- result = given(passedArgsSoFar);
- }
- return result;
- };
- }
- return given([]);
- }
- /**
- * Creates the functions that returns the function with cached arguments. If count if passed arguments will be matched
- * to the arguments defined in `func` then function will be invoked.
- * Arguments are added to the stack in direction from the right to the left.
- *
- * @example
- * ```
- * var replace = curry(function(find, replace, string) {
- * return string.replace(find, replace);
- * });
- *
- * // returns function with bounded first argument
- * var replace = replace('Some test with foo...')
- *
- * // returns replaced string - all arguments was passed so function was invoked
- * replace('bar', 'foo');
- *
- * ```
- *
- * @param {Function} func Function to currying.
- * @returns {Function}
- */
- export function curryRight(func) {
- const argsLength = func.length;
- function given(argsSoFar) {
- return function _curry(...params) {
- const passedArgsSoFar = argsSoFar.concat(params.reverse());
- let result;
- if (passedArgsSoFar.length >= argsLength) {
- result = func.apply(this, passedArgsSoFar);
- } else {
- result = given(passedArgsSoFar);
- }
- return result;
- };
- }
- return given([]);
- }
|