1,节流

  节流就是对连续的函数触发,在设定的间隔时间段内,只让其执行一次。

  先来看看js高级程序设计3里面节流的代码

function throttle (method, context, wait) {
clearTimeout(method.tId)
method.tId = setTimeout(function () {
method.call(context)
}, wait)
}

当函数连续执行的时候,如果之前的定时器还没执行,就把它清除了,再从新设置一个新的定时器。

  我们可以对这个进行改进

function throttle (fn, wait) {
let timeout;
let prevTime = 0;
return function(...args) { //返回一个函数
let now = new Date();
let remaining = wait - (now - prevTime) // 下一次执行的时间,
if (remaining <=0 || remaining > wait) { // 如果下一次的时间小于等于0,立刻执行一次函数,并把时间戳改为当前的时间。
clearTimeout(timeout)
timeout = null
prevTime = now
fn.apply(this, args)
} else if (!timeout) { // 如果当前没有定时器 那么就新加一个定时器。
timeout = setTimeout(() => {
timeout = null;
prevTime = new Date();
fn.apply(this, args)
}, remaining)
}
}
}

  第一次执行: timeout为undefined, prevTime为0     remaining为负数,走if的第一个,立即执行了函数并将下次时间改成当前时间

  第二次执行: 下一次时间为正,定时器还是为undefined,走if的第二个,设置定时器

     下一次执行(不超过wait时间内) :  remaining大于0,定时器为true,所以直接跳出

  

    understore里面的节流考虑了两个高级的配置:  是否在第一次触发的时候就执行函数 和  最后一次的定时器触发的执行函数。还提供了节流的取消函数。

function throttle(fn, wait, option = {}) {
let timeout;
let prevTime = 0
let throttled = function(...args){
let now = new Date();
if (!prevTime && option.leading === false) prevTime = now;
let remaining = wait - (now - prevTime);
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout)
timeout = null;
}
prevTime = now
fn.apply(this, args)
} else if (!timeout && option.trailing !== false) {
timeout = setTimeout(() => {
prevTime = option.leading === false ? 0 : new Date;
fn.apply(this, args)
})
}
}
throttled.cancel = () => {
clearTimeout(timeout);
prevTime = 0;
timeout = null;
}
return throttled
}

  除了加了两个配置项和取消函数,别的基本都是一样的。

  需要注意的是,首次不执行和最后不执行这两个不能同时配置,只能配置一个。

2,防抖

  其实我感觉防抖和节流差别不大,主要的差别在于: 在wait的时间内,反复触发函数的话,节流不会理会这些,而防抖的话,只要你触发了,他就会清除之前的定时器,从新设置一个定时器。

  比如说坐电梯,如果是节流的话,电梯等待时间为5S,从第一个人进电梯开始算,到5S后他就会关门运行。

           如果是防抖的话,电梯等待时间为5S,在这5S之内,如果有人进电梯,他就会重新计时,只有在5S中没有人进电梯了,电梯才关门运行。

function debounce (fn, wait) {
let timeout;
return function(...args) {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}

  返回一个函数, 先清除之前的定时器,然后再新加定时器。

  underscore里面的防抖添加了一个高级配置,是否立即执行一次函数。

function debounce(fn, wait, immediate) {
let timeout;
return function(...args) {
let callNow = immediate && !timeout;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
timeout = null;
if (!immediate) fn.apply(this, args)
}, wait)
if (callNow) fn.apply(this, args)
}
}

  这里添加了immediate这个配置项,如果为true的话,那么触发第一次的时候就执行了要执行的函数,定时器里面不执行。

  

  

js的节流和防抖的更多相关文章

  1. js 函数节流和防抖

    js 函数节流和防抖 throttle 节流 事件触发到结束后只执行一次. 应用场景 触发mousemove事件的时候, 如鼠标移动. 触发keyup事件的情况, 如搜索. 触发scroll事件的时候 ...

  2. JS 函数节流与防抖

    前言 事件的触发权很多时候属于用户,可能会出现下列问题: 向后台发送数据,用户频繁触发,对服务器造成压力: 一些浏览器事件,如window.onresize,window.mousemove等,触发的 ...

  3. JS函数节流和防抖

    看JS高级程序设计时,了解到一个概念--函数节流,是为了防止在高频率触发某些事件导致浏览器崩溃.最近又了解到另一个概念,防抖,感觉和函数节流很像,也查看了很多篇博文,算是理解了. 区别: 函数节流:频 ...

  4. JS的节流、防抖及使用场景

    前言 据说阿里有一道面试题就是谈谈函数节流和函数防抖. 糟了,这可触碰到我的知识盲区了,好像听也没听过这2个东西,痛定思痛,赶紧学习学习.here we go! 概念和例子 函数防抖(debounce ...

  5. js函数节流和防抖的理解与实现

    一:函数防抖1.理解:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间2.思路:每次触发事件时都取消之前的延时调用方法 3.实现: function debounce ...

  6. js的节流、防抖以及使用场景

    介绍 首先看一个没有经过任何处理的: 1 // 模拟一个输出的函数 2 function input(value) { 3 console.log(`输入的内容${value}`) 4 } 5 con ...

  7. 7分钟理解JS的节流、防抖及使用场景

    前言 据说阿里有一道面试题就是谈谈函数节流和函数防抖.糟了,这可触碰到我的知识盲区了,好像听也没听过这2个东西,痛定思痛,赶紧学习学习.here we go! 概念和例子 函数防抖(debounce) ...

  8. 一文理解JS的节流、防抖及使用场景

    函数防抖(debounce):在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时. 看一个

  9. js函数的节流和防抖

    js函数的节流和防抖 用户浏览页面时会不可避免的触发一些高频度触发事件(例如页面 scroll ,屏幕 resize,监听用户输入等),这些事件会频繁触发浏览器的重拍(reflow)和重绘(repai ...

随机推荐

  1. 设计模式(java)--中介者模式之同事的关联

    转自:http://blog.csdn.net/zhengzhb/article/details/7430098 定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使 ...

  2. win7 iis7 ftp配置

    1.安装ftp服务器 开始菜单找到控制面板>在左侧找到打开或关闭windows功能点击 弹出如下对话框, 在弹出的对话框中找到Internet信息服务,如下 然后如上图所示,选中ftp服务器复选 ...

  3. 编写高质量代码改善C#程序的157个建议——建议102:区分接口和抽象类的应用场合

    建议102:区分接口和抽象类的应用场合 接口和抽象类有一些显而易见的区别: 接口支持多继承,抽象类则不能. 接口可以包含方法.属性.索引器.事件的签名,但不能有实现,抽象类则可以. 接口在增加新方法后 ...

  4. 使用 JAVA 中的动态代理实现数据库连接池

    数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈.我们可以在互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共 ...

  5. await Task传异步Lambda问题

    微软在.NET4.5中升级了C#语言到5.0,加入了await和async语法,极大地方便了广大开发人员的异步编程,也是为了和WinRT API配套,因为这套API充满了异步编程. 在开发过程中发现有 ...

  6. C# 利用CMD命令行结束进程

    public static void CmdKillProcess(int pid)        {            string cmdStr = string.Format("t ...

  7. [JQuery]ScrollMe滚动特效插件

    最近考完试,一切顺利,昨晚闲着无聊把最近要用的一个插件翻译了一下:ScrollMe. (╯‵□′)╯︵┻━┻地址请戳: /* ScrollMe -李明夕翻译(╯‵□′)╯︵┻━┻ */ ScrollM ...

  8. c#中关于协变性和逆变性(又叫抗变)帮助理解

    今天回忆了之前看的<深入理解C#>这本书中的泛型章节,其中对泛型的可变性的理解.泛型可变性分两种:协变和逆变.逆变也又称为抗变. 怎么理解这两个名词的意思: ①:协变即为在泛型接口类型中使 ...

  9. MySQL数据库(三)

    1. 创建表 create table student( id int unsigned not null auto_increment primary key, name varchar(8) no ...

  10. MySQL MGR实现分析 - 成员管理与故障恢复实现

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MySQL Group Replication(MGR)框架让MySQL具备了自动主从切换和故障恢复能力,举 ...