Серия тем по JavaScript — стабилизация и регулирование

JavaScript

1. Введение

Вообще говоря, в этом абзаце в основном речь идет об общем обзоре каких-то знаний, что не так важно и равносильно аннотации статьи. Но есть кое-что необычное.Например,эта статья очень важна для понимания понятий anti-shake и throttling.Очень важно.

1.1 Причины появления

Первое, на что следует указать, это почему появляются эти две идеи.

1. Поскольку невооруженным глазом можно различить изменения только определенной частоты, то есть изменение в 1000 раз в течение 1 с равносильно изменению в 60 раз для человеческих органов чувств Точно так же это можно сравнить с кодом js. Код не обязательно должен выполняться очень много раз за заданный период времени. Достаточно достичь определенной частоты. Потому что чем больше вы бегаете, тем эффект тот же.

2. Проблемы с производительностью клиента. Как мы все знаем, в настоящее время по-прежнему очень важно быть совместимым с соответствующим интерфейсом, а основная точка совместимости — это low-end модели, поэтому нам необходимо контролировать количество выполнений js-кода в разумных пределах. спектр. Он может не только сэкономить ресурсы процессора браузера, но и сделать просмотр страниц более плавным, и не будет зависать из-за выполнения js.

Выше приведены основные причины появления функции троттлинга и функции антивстряски.

1.2 Концептуальное понимание

Я так много сказал выше, просто чтобы объяснить, почему существуют две реализации анти-тряски и дросселирования. Давайте визуализируем разницу между этими двумя идеями. Я часто путаю эти две идеи, поэтому на этот раз Намеренно придумал хороший способ запомнить.

1.регулирование функцииЭто означает, что метод JS работает только один раз в определенный период времени.

дросселированиеэкономить воду смысл, точно так же, как кран с проточной водой, мы можем вручную уменьшить поток воды (на определенный период времени), но он будет продолжать течь.

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

2.Функция защиты от тряскиСвободного времени хватает только на один раз выполнить код.

Например, в жизни поездка на автобусе означает, что в течение определенного периода времени, если люди будут проводить карты одну за другой, чтобы сесть в автобус, водитель не будет водить машину. Водитель сядет за руль только в том случае, если никто другой не украл карту. (На самом деле, пока вы помните идею троттлинга, вы можете судить о троттлинге и антитряске методом исключения)

2. Код

2.1 Стабилизация изображения

Хотя вы запускаете событие, но я должен выполнить только после события Trigger N секунды, если вы запускаете событие в течение нескольких секунд, сработало это событие, то я найму время на новые события, n секунд после короткого исполнения, - это ждать Для вас, чтобы закончить событие Trigger, больше не запускает события в течение n секунд, я выполняю!

function debounce(func, waitTime) {
  var timeout;
  return function () {
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(func, waitTime);
  }
}
document.querySelector('#app').onmousemove = debounce(fn, 1000);

Вы можете видеть, что приведенные выше строки кода используют знание замыканий, Основная цель — сохранить переменную тайм-аута после выполнения функции.

Есть еще один момент, который у некоторых друзей может вызвать сомнения. Зачем возвращать функцию здесь? На самом деле это легко понять, мы можем посмотреть на следующий код

var timeout;
function debounce(func, waitTime) {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(func, waitTime);
}
container.onmousemove = debounce(getUserAction, 1000);

Я вручную удалил возврат в функции debounce, а затем, чтобы сохранить тайм-аут, я поместил его в глобальную переменную, эти строки кода очень похожи на приведенные выше, но вы можете запустить этот код напрямую и обнаружить, что debounce будет только сделать это один раз! ! !

Хахаха, на самом деле причина, по которой функция возвращается в функции debounce, заключается в том, что onmousemove нужно привязатьфункция, наш тестовый код вернет undefined только после его однократного выполнения, что эквивалентно

container.onmousemove = debounce(getUserAction, 1000);
container.onmousemove = undefined;

Разумеется, право на привязку события отсутствует. Если хорошо с точки зрения понимания написать, на самом деле думаю, что это может связать следующее

var timeout;
function debounce(func, waitTime) {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(func, waitTime);
}
container.onmousemove = () => {
  debounce(getUserAction, 1000);
}

Все следующие методы работают так же, как и первая функция.

Но в этой версии кода мы печатаем это и объекты событий в fn и обнаруживаем, что что-то не так.

Как видно из рисунка выше, объекты this и event в fn не ожидаются, поэтому нам нужно вручную передать this и объекты event в функцию fn. Итак, функция защиты от сотрясений второй версии ниже.

function debounce(func, waitTime) {
  var timeout;
  return function () {
    var context = this,
        args = arguments;
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(function () {
      func.apply(context, args)
    },  waitTime);
  }
}

2.2 Дросселирование

Продолжим рассмотрение логики кода идеи дросселирования.

Используя временную метку, при срабатывании события вынимаем текущую временную метку, затем вычитаем предыдущую временную метку (начальное значение равно 0), если она больше установленного временного периода, выполняем функцию, а затем обновляем timestamp to Текущая временная метка, если она меньше этой, не выполняется.

function throttle(func, waitTime) {
    var context,
        args,
        previous = 0;
    return function() {
        var now = + new Date();
            context = this;
            args = arguments;
        if (now - previous > waitTime) {
            func.apply(context, args);
            previous = now;
        }
    }
}

Или мы можем использовать таймер для регулирования.

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

function throttle(func, waitTime) {
    var timeout,
        previous = 0;
    return function() {
        context = this;
        args = arguments;
        if (!timeout) {
            timeout = setTimeout(function(){
                timeout = null;
                func.apply(context, args)
            }, waitTime)
        }

    }
}

3. Знания в навыки

В 2018 году моей самой большой мыслью было попытаться превратить полученные знания в навыки (от Лао Яо [nuggets.capable/post/684490…](В 2018 году я получил 5 познаний, все из которых оглушительны | Ежегодное эссе Nuggets))

Знания можно получить, а навыки можно только приобрести.

В вышеуказанных двух частях мы все изучаем причины появления антишейков и троттлингов, соответствующие понятия и идеологическую логику реализации.Это все знания.Теперь превратим полученные знания в навыки и будем стремиться стать часть нашего собственного проекта Бар.

Для таких функций, как защита от сотрясений и регулирование скорости, мы можем поместить их в общедоступные файлы и вызывать их напрямую там, где это необходимо.

Основное основное применение защиты от сотрясений и регулирования — оптимизация производительности кода, которую можно использовать во многих местах, таких как проверка поля ввода, отложенная загрузка изображений, различные часто инициируемые события DOM и т. д.

Ниже показан мастер кнопок, который я смоделировал и написал поиск Baidu. На рисунке 1 показано, что я не использовал поиск с защитой от сотрясений. Я нашел это ключевое слово и инициировал несколько запросов N, а затем изменил строку кода, чтобы добавить защиту от сотрясений. , и ситуация с запросом изменилась. становится рис. 2. Эффект очевиден.

this.debounce(this.getData, 1000)();

об авторе

Дао Фэн, инженер по развитию передней части Тонгбанской улицы, присоединился к команде в апреле 2018 года и в настоящее время в основном несет ответственность за разработку проектов по бокам приложений на работе.

Для получения более интересного контента отсканируйте код, чтобы подписаться на общедоступную учетную запись WeChat «Tongbanjie Technology».