/**
 * @파일 fn.js
 * @모듈 fn
 */
import { newGUID } from './guid.js';
'글로벌/창'에서 창 가져오기;

내보내기 const UPDATE_REFRESH_INTERVAL = 30;

/**
 * 바인드(프록시 또는 컨텍스트라고도 함). 컨텍스트를 변경하는 간단한 방법
 * 함수.
 *
 * 또한 함수에 고유 ID를 저장하므로 쉽게 제거할 수 있습니다.
 * 이벤트.
 *
 * @기능
 * @param {혼합} 컨텍스트
 * 범위로 바인딩할 개체입니다.
 *
 * @param {함수} fn
 * 범위에 바인딩되는 함수입니다.
 *
 * @param {숫자} [UID]
 * 설정할 기능에 대한 선택적 고유 ID
 *
 * @return {함수}
 * 주어진 컨텍스트에 바인딩될 새 함수
 */
내보내기 const 바인드 = 기능(컨텍스트, fn, uid) {
  // 함수에 고유한 ID가 있는지 확인합니다.
  if (!fn.guid) {
    fn.guid = newGUID();
  }

  // 컨텍스트를 변경하는 새 함수를 만듭니다.
  const bound = fn.bind(context);

  // 이 기능을 개별화할 수 있는 기능 허용
  // 여러 객체가 동일한 프로토타입을 공유할 수 있는 경우에 필요합니다.
  // 두 항목이 동일한 기능을 가진 이벤트 리스너를 추가하는 경우 하나만 제거하려고 합니다.
  // 둘 다 동일한 GUID를 가지므로 둘 다 제거됩니다.
  // 이것을 사용할 때 리스너를 제거할 때에도 bind 메소드를 사용해야 합니다.
  // 현재 텍스트 트랙에서 사용됨
  bound.guid = (UID) ? uid + '_' + fn.guid : fn.guid;

  리턴 바운드;
};

/**
 * 주어진 함수 `fn`을 `fn`만 호출하는 새 함수로 래핑합니다.
 * 매 `wait` 밀리초당 최대 한 번.
 *
 * @기능
 * @param {함수} fn
 * 제한할 기능입니다.
 *
 * @param {숫자} 대기
 * 제한할 시간(밀리초)입니다.
 *
 * @return {함수}
 */
내보내기 const 스로틀 = function(fn, wait) {
  let last = window.performance.now();

  const throttled = function(...args) {
    const now = window.performance.now();

    if (지금 - 마지막 > = 대기) {
      fn(...인수);
      마지막 = 지금;
    }
  };

  제한된 반환;
};

/**
 * `wait` 이후까지 `func` 호출을 지연시키는 디바운스된 함수를 생성합니다.
 * 디바운스된 함수가 마지막으로 발생한 이후 밀리초가 경과했습니다.
 * 호출.
 *
 * lodash 및 underscore 구현에서 영감을 얻음.
 *
 * @기능
 * @param {함수} 함수
 * 디바운스 동작으로 래핑하는 기능.
 *
 * @param {숫자} 대기
 * 마지막 호출 후 대기하는 시간(밀리초)입니다.
 *
 * @param {부울} [즉시]
 * 생성 즉시 함수를 호출할지 여부.
 *
 * @param {객체} [컨텍스트=창]
 * 디바운스된 함수가 디바운스되어야 하는 "컨텍스트". 을 위한
 * 예를 들어, 이 기능을 Video.js 플레이어에 연결해야 하는 경우,
 * 플레이어는 여기로 넘어갈 수 있습니다. 또는 기본값은
 * 전역 `창` 객체.
 *
 * @return {함수}
 * 디바운스된 함수.
 */
내보내기 const 디바운스 = function(func, 대기, 즉시, 컨텍스트 = 창) {
  타임아웃하자;

  const 취소 = () => {
    context.clearTimeout(timeout);
    타임아웃 = null;
  };

  /* eslint-disable consistent-this */
  const 디바운스 = function() {
    const 자기 = this;
    const 인수 = 인수;

    나중에 하자 = function() {
      타임아웃 = null;
      나중에 = null;
      if (! 즉시) {
        func.apply(self, args);
      }
    };

    if (!타임아웃 && 즉각적인) {
      func.apply(self, args);
    }

    context.clearTimeout(timeout);
    timeout = context.setTimeout(나중, 대기);
  };
  /* eslint-enable consistent-this */

  debounced.cancel = 취소;

  디바운스 반환;
};