'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _this = undefined;
/**
 * 防抖，场景：搜索
 *
 * 触发事件后在 n 秒内函数只能执行一次，如果
 * 在 n 秒内又触发了事件，则会重新计算函数执行时间
 *
 * @param {Function} fn 主函数
 * @param {number} time 间隔时间，单位 `ms`
 * @param {boolean} immediate 是否立即执行，默认 `false`
 * @returns 闭包函数
 *
 * @example
 *
 * ```ts
 * function count() {
 *  console.log('xxxxx')
 * }
 * window.onscroll = debounce(count, 500)
 *
 * window.onscroll = debounce(count, 500, true)
 * ```
 */
function debounce(fn, time) {
  var immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  var timer;
  var result;
  return function () {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    // @ts-ignore
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    var that = this;
    // 只有 timer 不存在（即冷却期已过）才立即执行
    var callNow = immediate && !timer;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      timer = null;
      if (!immediate) {
        result = fn.apply(that, args);
      }
    }, time);
    if (callNow) {
      result = fn.apply(that, args);
    }
    return result;
  };
}
/**
 * 不用生成中间函数的防抖
 *
 * @example
 * ```ts
 * debounceRun(func, args, {
 *   funcKey: 'funcKey',
 *   wait: 500, // 默认 500
 *   throttle: false, // 是否是节流，默认 false
 *   immediate: true, // 是否立即执行，默认 true
 * })
 * ``
 */
var debounceRun = function () {
  // 储存方法的 timer 的 map
  var timerMap = new Map();
  return function (func) {
    var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    var _a, _b, _c, _d;
    var DEFAULT_OPTIONS = {
      funcKey: null,
      wait: 500,
      throttle: false,
      immediate: true,
      debug: false
    };
    // 如果没有 funcKey 那么直接使用 func 作为 map 的 key
    var funcKey = options.funcKey || func;
    var wait = (_a = options.wait) !== null && _a !== void 0 ? _a : DEFAULT_OPTIONS.wait;
    var throttle = (_b = options.throttle) !== null && _b !== void 0 ? _b : DEFAULT_OPTIONS.throttle;
    var immediate = (_c = options.immediate) !== null && _c !== void 0 ? _c : DEFAULT_OPTIONS.immediate;
    var debug = (_d = options.debug) !== null && _d !== void 0 ? _d : DEFAULT_OPTIONS.debug;
    // 先看看 map 里面是否有 timer，有 timer 代表之前调用过
    var timer = timerMap.get(funcKey);
    if (immediate) {
      func.apply(_this, args);
    }
    if (timer) {
      if (debug) {
        console.log('>>> debounceRun cached');
      }
      if (throttle) {
        return;
      }
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      // 先把这个方法从 map 里面删掉
      timerMap["delete"](funcKey);
      func.apply(_this, args);
      if (debug) {
        console.log('>>> debounceRun executing func');
      }
    }, wait);
    // 将方法的 timer 存进 map， key 是 funcKey
    timerMap.set(funcKey, timer);
  };
}();

exports.debounce = debounce;
exports.debounceRun = debounceRun;
