Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

函数节流与函数防抖 #97

Closed
islishude opened this issue Aug 21, 2017 · 0 comments
Closed

函数节流与函数防抖 #97

islishude opened this issue Aug 21, 2017 · 0 comments
Labels

Comments

@islishude
Copy link
Owner

islishude commented Aug 21, 2017

什么是函数节流与函数防抖

举个栗子,我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。再举个栗子,假设电梯一次只能载一人的话,10 个人要上楼的话电梯就得走 10 次,是一种浪费资源的行为;而实际生活正显然不是这样的,当电梯里有人准备上楼的时候如果外面又有人按电梯的话,电梯会再次打开直到满载位置,从电梯的角度来说,这时一种节约资源的行为(相对于一次只能载一个人)。

  • 函数节流: 指定时间间隔内只会执行一次任务;
  • 函数防抖: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

函数节流的核心是,让一个函数不要执行得太频繁,减少一些过快的调用来节流。函数去抖就是对于一定时间段的连续的函数调用,只让其执行一次。

实现

函数节流

函数节流应用的实际场景,多数在监听页面元素滚动事件的时候会用到。因为滚动事件,是一个高频触发的事件。以下是监听页面元素滚动的示例代码:

function throttle(fn, wait) {
    var previous = 0
    var timer = null
    return function () {
        var context = this
        var args = arguments
        if (!previous) {
            previous = Date.now()
            fn.apply(context, args)
        } else if (previous + wait >= Date.now()) {
            if (timer) {
                // console.log(timer)
                clearTimeout(timer)
                timer = null
            }
            // console.log(timer)
            timer = setTimeout(function () {
                // console.log(timer)
                previous = Date.now()
                fn.apply(context, args)
            }, wait)
        } else {
            previous = Date.now()
            fn.apply(context, args)
        }
    }
}

throttle 应用场景

函数节流有哪些应用场景?哪些时候我们需要间隔一定时间触发回调来控制函数调用频率?

  • DOM 元素的拖拽功能实现(mousemove)
  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
  • 计算鼠标移动的距离(mousemove)
  • Canvas 模拟画板功能(mousemove)
  • 搜索联想(keyup)
  • 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次

函数防抖

function debounce(fn, wait) {
    var timer = null;
    return function () {
        var context = this
        var args = arguments
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }
        timer = setTimeout(function () {
            fn.apply(context, args)
        }, wait)
    }
}

debounce 应用场景

函数去抖有哪些应用场景?哪些时候对于连续的事件响应我们只需要执行一次回调?

  • 每次 resize/scroll 触发统计事件
  • 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)

ref: http://justclear.gitlab.io/throttle-and-debounce/
ref: https://segmentfault.com/a/1190000008768202
ref: lessfish/underscore-analysis#20
ref: http://www.cnblogs.com/fsjohnhuang/p/4147810.html

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant