JS просто реализует анти-тряску и дросселирование

внешний интерфейс JavaScript

1. Что такое анти-шейк и троттлинг

Ps: Например, окно поиска, которое пользователь использует при наборе текста.changeСобытия для вызова поиска, если пользователь ищет каждый вход, он будет потреблять много ресурсов сервера, даже если ресурсы вашего сервера очень мощные, такой вещи нет.

1. Дебунс - дебунс

Одно из решений заключается в том, что каждый раз, когда пользователь перестает печатать, задерживать более500ms, только искать на этот разString, это защита от сотрясений.

  • Обоснование: объединить несколько вызовов функций в один и вызывать только один раз по истечении заданного времени.
  • Код:
function debounce(fn, delay) {
  // 维护一个 timer,用来记录当前执行函数状态
  let timer = null;

  return function() {
    // 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
    let context = this;
    let args = arguments;
    // 清理掉正在执行的函数,并重新执行
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}
let flag = 0; // 记录当前函数调用次数
// 当用户滚动时被调用的函数
function foo() {
  flag++;
  console.log('Number of calls: %d', flag);
}

// 在 debounce 中包装我们的函数,过 2 秒触发一次
document.body.addEventListener('scroll', debounce(foo, 2000));
  1. debounceПосле того, как функция инкапсулирована, верните внутреннюю функцию
  2. Каждый раз, когда запускается событие, текущийtimerЗатем сбросьте тайм-аут и позвоните. Это приведет к тому, что каждое высокочастотное событие отменит предыдущий вызов тайм-аута, в результате чего обработчик события не будет запущен.
  3. Только когда высокочастотное событие прекращается, последний вызов тайм-аута, инициированный событием, можетdelayвыполнить по прошествии времени

2. Дроссель - дроссель

другое решение, чемСтабилизаторБудьте более расслаблены. В настоящее время мы не хотим, чтобы пользователи вводили данные вслепую, но даем им некоторые подсказки для поиска, поэтому мы ограничиваем каждый проход.500msпросто спросите в это времяString, который дросселирует.

  • Принцип: независимо от того, как часто запускается событие, функция регулирования гарантирует, что реальная функция обработки события будет выполняться в течение заданного времени.
  • Есть две реализации кода, одна - отметка времени, а другая - таймер. 1) Реализация метки времени:
function throttle(func, delay){
  let prev = Date.now();
  return function(){
    const context = this;
    const args    = arguments;
    const now     = Date.now();
    if(now - prev >= delay){
      func.apply(context, args);
      prev = Date.now();
    }
  }
}

Когда срабатывает высокочастотное событие, оно должно выполняться немедленно в первый раз (если интервал между функцией привязки события и фактическим событием триггера больше, чемdelay), а затем как часто событие срабатывает, оно всегда будетdelayВыполняется только один раз в секундах. И когда сработает последнее событие, событие больше не будет выполняться.

2) Реализация таймера: Когда событие срабатывает, мы устанавливаем таймер, и когда событие срабатывает снова, если таймер существует, он не будет выполняться; до тех пор, покаdelayЧерез несколько секунд таймер выполняет функцию выполнения, которая очищает таймер, чтобы можно было установить следующий таймер.

fucntion throttle(func, delay){
  let timer = null;

  return funtion(){
    let context = this;
    let args    = arguments;
    if(!timer){
      timer = setTimeout(function(){
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  }
}

Когда событие срабатывает в первый раз, функция определенно выполняется не сразу, а через некоторое время.delayсекунд спустя. После этого событие постоянно срабатывает, и каждыйdelayВыполнять раз в секунду. После последней остановки стрельбы из-за срабатывания таймераdelayЗадержка и, возможно, выполнение функции один раз.

3) Функция регулирования, которая всесторонне использует метки времени и таймеры для немедленного выполнения при запуске события, а также может выполняться один раз после запуска.

function throttle(func, delay){
  let timer = null;
  let startTime = Date.now();

  return function(){
    let curTime = Date.now();
    let remaining = delay - (curTime - startTime);
    const context = this;
    const args = arguments;

    clearTimeout(timer);
    if(remaining <= 0){
      func.apply(context,args);
      startTime = Date.now();
    }else{
      timer = setTimeout(func, remaining);
    }
  }
}

требуется в каждомdelayФункция всегда выполняется однократно, поэтому внутри функции дроссельной заслонки используется время начала, текущее время иdelayвычислятьremaining,когдаremaining <= 0Когда это означает, что пора выполнять функцию, если она еще не наступила, установите ее наremainingТриггер по истечении времени. Конечно вremainingЕсли событие произойдет снова в течение этого периода, текущий таймер будет отменен, а новый таймер будет пересчитан.remainingдля определения текущего состояния.