博客
关于我
JS魔法堂:函数节流(throttle)与函数去抖(debounce)
阅读量:429 次
发布时间:2019-03-06

本文共 3060 字,大约阅读时间需要 10 分钟。

debounce与throttle:JavaScript事件防抖动的两种解决方案


前言

在实际开发中,频繁触发DOM操作或资源加载可能导致UI卡顿甚至浏览器崩溃。以下场景经常引发问题:

  • window对象的resize、scroll事件
  • 拖拽时的mousemove事件
  • 射击游戏中的mousedown、keydown事件
  • 文字输入、自动完成的keyup事件
  • 针对这些事件,有两种常见的解决方案:debouncethrottle


    debounce:防抖动机制的定义

    debounce 的核心思想是:在指定的空闲时间内,多次触发同一事件只执行一次。类似于弹簧的状态,只有在手松开后才会恢复原状。

    简单实现:

    var debounce = function(idle, action) {    var last = null;    return function() {        var ctx = this;        var args = arguments;        clearTimeout(last);        last = setTimeout(function() {            action.apply(ctx, args);        }, idle);    };};

    throttle:速率限制机制的定义

    throttle 的目标是限制事件处理的执行频率。每隔指定时间执行一次相关操作,类似于水流的滴落。

    简单实现:

    var throttle = function(delay, action) {    var last = 0;    return function() {        var curr = +new Date();        if (curr - last > delay) {            action.apply(this, arguments);            last = curr;        }    };};

    Underscore v1.7.0的实现剖析

    _.throttle函数

    _.throttle = function(func, wait, options) {    var context, args, result;    var timeout = null;    var previous = 0;    if (!options) options = {};    var later = function() {        previous = options.leading === false ? 0 : _.now();        timeout = null;        result = func.apply(context, args);        if (!timeout) context = args = null;    };    return function() {        var now = _.now();        if (!previous && options.leading === false) previous = now;        var remaining = wait - (now - previous);        context = this;        args = arguments;        if (remaining <= 0 || remaining > wait) {            if (timeout) {                clearTimeout(timeout);                timeout = null;            }            previous = now;            result = func.apply(context, args);            if (!timeout) context = args = null;        } else if (!timeout && options.trailing !== false) {            timeout = setTimeout(later, remaining);        }        return result;    };};

    精彩之处

    • remaining <= 0 用于检测是否满足空闲时间。
    • remaining > wait 用于处理时间异常(如系统时间修改)。

    _.debounce函数

    _.debounce = function(func, wait, immediate) {    var timeout, args, context, timestamp, result;    var later = function() {        var last = _.now() - timestamp;        if (last < wait && last > 0) {            timeout = setTimeout(later, wait - last);        } else {            timeout = null;            if (!immediate) {                result = func.apply(context, args);                if (!timeout) context = args = null;            }        }    };    return function() {        context = this;        args = arguments;        timestamp = _.now();        var callNow = immediate && !timeout;        if (!timeout) timeout = setTimeout(later, wait);        if (callNow) {            result = func.apply(context, args);            context = args = null;        }        return result;    };};

    精彩之处

    • 递归调用 setTimeout 来确保在空闲时间内只执行一次函数。
    • immediate 参数控制是否在首次调用时立即执行函数。

    总结

    debouncethrottle 都通过减少事件处理的执行频率来提升性能,但核心机制有明显差异:

    • debounce 更关注空闲时间,适用于需要延迟处理的场景。
    • throttle 则强调执行频率,适用于需要稳定化处理的场景。

    选择时需结合具体需求,结合各JS库的实现进行深入理解。


    参考

    你可能感兴趣的文章
    Objective-C实现RodCutting棒材切割最大利润算法(附完整源码)
    查看>>
    Objective-C实现Romberg算法(附完整源码)
    查看>>
    Objective-C实现round robin循环赛算法(附完整源码)
    查看>>
    Objective-C实现RRT路径搜索(附完整源码)
    查看>>
    Objective-C实现rsa 密钥生成器算法(附完整源码)
    查看>>
    Objective-C实现RSA密码算法(附完整源码)
    查看>>
    Objective-C实现runge kutta龙格-库塔法算法(附完整源码)
    查看>>
    Objective-C实现segment tree段树算法(附完整源码)
    查看>>
    Objective-C实现selection sort选择排序算法(附完整源码)
    查看>>
    Objective-C实现sha256算法(附完整源码)
    查看>>
    Objective-C实现shell sort希尔排序算法(附完整源码)
    查看>>
    Objective-C实现sieveOfEratosthenes埃拉托色尼筛法求素数算法 (附完整源码)
    查看>>
    Objective-C实现SinglyLinkedList单链表算法(附完整源码)
    查看>>
    Objective-C实现skew heap倾斜堆算法(附完整源码)
    查看>>
    Objective-C实现Skip List跳表算法(附完整源码)
    查看>>
    Objective-C实现slack message松弛消息算法(附完整源码)
    查看>>
    Objective-C实现slow sort慢排序算法(附完整源码)
    查看>>
    Objective-C实现tanh函数功能(附完整源码)
    查看>>
    Objective-C实现z-algorithm算法(附完整源码)
    查看>>
    Objective-C实现zellers congruence泽勒一致算法(附完整源码)
    查看>>