Нет функции дросселирования и защиты от сотрясений, посмотрите на эту сумку для обучения.

JavaScript

предисловие

Front-end разработка будет сталкиваться с некоторыми частыми триггерами событий, такими как: прокрутка окна, изменение размера, mousedown, mousemove, keyup, keydown и т. д. Если вы ничего не сделаете со своим кодом, вы обнаружите, что страница зависает и срабатывает интерфейсные запросы и другие проблемы, в этой статье будет проанализирована реализация функции троттлинга и анти-шейка, и постепенно шаг за шагом будет раскрыто истинное лицо функции троттлинга и анти-шейка💜

концепция

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

Функция debounce (дебаунс)

当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间,不会执行

Поймите принцип:
Несмотря на то, что событие запускается, оно должно быть выполнено через n секунд после запуска события.Если событие запускается снова в течение n секунд после запуска события, время нового события имеет преимущественную силу, и оно будет выполнено через n секунд Короче говоря, необходимо, чтобы Он не выполнялся до тех пор, пока событие больше не будет срабатывать в течение n секунд после срабатывания события!

функция дроссельной заслонки

预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期

Поймите принцип:
Функция гарантированно будет выполнена один раз за указанное время

выполнить

Стабилизатор

В соответствии с принципом защиты от сотрясений код реализации выглядит следующим образом, и следующие примеры будут использоваться регулярно:

# 箭头log函数
let count = 0
const log = () => {
    console.log(this)
    ++count
    console.log(count)
}
# 函数表达式
const log = function (evt) {
    console.log(this)
    console.log(evt)
    ++count
    console.log(count)
}
const debounce = function (fn, delay){
    let timeout = null
    return function () {
        if (timeout) {
            clearTimeout(timeout)
        }
        timeout = setTimeout(fn, delay)
    }
}

Возьмем в качестве примера частые клики.
Обычное использование: meContain.onclick = debounce(log, 1000)
react demo: ...onClick={debounce(log.bind(this), 1000)}

В этом примере вы обнаружите, что если вы часто нажимаете в течение 1 секунды, журнал будет выводиться в конце, что подтверждает принцип защиты от сотрясений.

Вы, ребята, обнаружили, что функция защиты от сотрясений все еще несовершенна?

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

это указывает на объект события

это указывает на

  • В функции журнала console.log(this), когда функция debounce не используется, значение this равно: undefined, это связано с тем, что используется функция стрелки, и когда вызывается onClick, bind(this), this указывает на пример компонента реакции
  • При обычном использовании console.log(this), когда функция устранения дребезга не используется, значение this равно:<div id="mecontain"></div>

объект события

  • Без функции debouce объект ClickEvent будет напечатан
  • В функции debounce он печатает только undefined

Чтобы решить вышеуказанные проблемы, изменить наш код

const debounce = function (fn, delay){
    let timeout = null
    return function () {
        const context = this;
        const args = arguments;
        clearTimeout(timeout)
        timeout = setTimeout(() => {
            fn.apply(context, args)
        }, delay)
    }
}

Интерактивный опыт оптимизации

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

const debounce = function (fn, delay,isImmeDiate= false){
    let timeout = null
    return function () {
        const context = this;
        const args = arguments;
        if(timeout) clearTimeout(timeout)
        if(isImmeDiate) {
            # 判断是否已经执行过,不要重复执行
            let callNow = !timeout
            timeout = setTimeout(function(){
                timeout = null;
             }, delay)
            if(callNow)  result = fn.apply(context, args)
        } else {
            timeout = setTimeout(() => {
                fn.apply(context, args)
            }, delay)
        }
        return result
    }
}

Если вы хотите добавить переключатель отмены дребезга, просто добавьте функцию отмены, чтобы очистить тайм-аут таймера = null

const debounce = function (fn, delay,isImmeDiate= false){
    let timeout = null
    const debounced =  function () {
        const context = this;
        const args = arguments;
        if(timeout) clearTimeout(timeout)
        if(isImmeDiate) {
            # 判断是否已经执行过,不要重复执行
            # setTimeout也是一直在更新的
            let callNow = !timeout
            timeout = setTimeout(function(){
                timeout = null;
             }, delay)
            if(callNow)  result = fn.apply(context, args)
        } else {
            timeout = setTimeout(() => {
                fn.apply(context, args)
            }, delay)
        }
        return result
    }
    debounced.prototype.cancle = function() {
        clearTimeout(timeout)
        timeout = null
    }
    return debounced
}

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

дросселирование

В соответствии с принципом дросселирования код реализации выглядит следующим образом, и следующие примеры будут использоваться регулярно:

Реализация метки времени

const throttle = function (fn, delay) {
    let preTime = 0;
    return function () {
        const context = this;
        const args = arguments;
        const now = +new Date();
        if (now - preTime > delay) {
            fn.apply(context, args);
            preTime = now;
        }
    }
}

Реализация таймера

const throttle = function (fn, delay) {
    let timeout = null
    return function () {
        const context = this;
        const args = arguments;
        if (!timeout) {
            timeout = setTimeout(function(){
                timeout = null
                fn.apply(context, args)
            }, delay)
        }
    }
}
# 如果需要立刻执行,其实变更下执行顺序即可
timeout = setTimeout(function(){
    timeout = null
    //fn.apply(context, args)
}, delay)
fn.apply(context, args)

Также используйте частые клики в качестве примера. Регулярное использование: meContain.onclick = дроссель (лог, 1000)

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

Вы нашли характеристики функции дросселирования на данный момент?

  • Временная метка будет выполнена немедленно, таймер будет выполнен в первый раз через n секунд
  • После того, как временная метка перестанет срабатывать, повторно выполнить событие невозможно.После того как таймер перестанет срабатывать, событие все равно будет выполнено снова.

Объедините две функции

const throttle = function (fn, delay) {
    let timeout = null
    let preTime = 0;
    const later = function() {
        preTime = +new Date()
        timeout = null
        fn.apply(context, args);
    }
    const throttled = function () {
        const context = this;
        const args = arguments;
        const now = +new Date();
        #下次触发fn剩余的时间
        const remaining = delay - ( now - preTime)
        #如果没有剩余的时间了或者系统时间变更
        if (remaining <= 0 || remaining > delay) {
            if(timeout) {
                clearTimeout(timeout)
                timeout = null
            }
            preTime = now
           fn.apply(context, args);
        } else if (!timeout) {
            timeout = setTimeout(later, remaining)
        }
    }
    throttled.cancel = function() {
        clearTimeout(timeout);
        previous = 0;
        timeout = null;
    }
    return throttled
}

Суммировать

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

Документация

Говоря о функции анти-встряски
регулирование функции
Функция защиты от тряски
регулирование функции

Саморекомендация

Углубитесь в исходный код, чтобы понять обработку ошибок Vue.
Webpack DllPlugin делает скорость сборки гладкой и шелковистой