JS 节流阀

参考 https://github.com/hahnzhu/read-code-per-day/issues/5

节流阀

节流阀的基本原理

事件函数的执行都记下当前时间, 只有当前时间与上次执行时间有一定间隔的时候才会去执行真正的逻辑

    function throttleMe(cb){
console.log('move');
var start = +new Date();
return function(){
var now = new Date();
if(now - start > 1000){
start = now;
cb();
}
}
}
$(window).on('mousemove', throttleMe(function(){
console.log('timer');
}));

有的书上是这么实现的 这个并不好用

var resizeTimer = null;
$(window).on('mousemove', function (e) {
console.log('move');
/* 第一次访问,不存在 resizeTimer,跳过这里 */
if (resizeTimer) {
clearTimeout(resizeTimer);
}
/* 第一次访问,赋值给 resizeTimer,绑定的函数 400ms 后调用 */
resizeTimer = setTimeout(function(){
console.log("move timer" /*+ e.clientX + '-' + e.clientY*/ );
}, 40);
});

发现实际中并不是40ms调用一次move timer

原因就在于timeout 它是等这个函数执行完之后间隔40ms 才有机会去执行下一个函数

    function throttle(func, wait) {
var context, args, timeout, result;
var previous = 0;
var later = function() {
previous = +new Date();
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = +new Date();
var remaining = wait - (now - previous); //距离下次执行剩余时间
console.log('remaining'+remaining + 'now'+ now);
context = this;
args = arguments;
if (remaining <= 0) { //过了间隔时间段 开始执行
clearTimeout(timeout);
timeout = null;
previous = now;
console.log('<0<0<0');
result = func.apply(context, args);
} else if (!timeout) {
console.log('set time out------------');
timeout = setTimeout(later, remaining);
}
return result;
};
}

函数去抖

    function debounce(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function() {
console.log('move');// 这个函数是mousemove事件处理的函数
var context = scope || this; var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function() {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
$('body').on('mousemove', function() {
console.log('move');
});
$('body').on('mousemove', debounce(function(event) {
console.log('tick');
}, 1000));

每次mousemove都是在执行 debounce返回的一个函数

这个返回的函数用到了debounce中的一个变量last

奇怪! 这个last 又不是全局的变量 为什么这个函数每次执行都依赖上次last的结果? 因为这里是一个闭包

通过闭包 使局部变量变成全局变量

因为这个a后面一直被fun函数使用 所以这个变量不会被销毁 正是闭包特性

function closure(){
var a = 1;
return function(){
return ++a;
}
}
fun = closure();
console.log(fun());//2
console.log(fun());//3
console.log(fun());//4

JS 节流阀的更多相关文章

  1. CSS3+JS切割轮播图

    以下说明数据,是指有4张图片的轮播图,分别切割成4张. 首先,做成单张切换的立体效果,即通过旋转,确定四张图片的位置,分别是一个立方体的上下前后的图片翻转移动角度. .box ul li:nth-ch ...

  2. 原生JS面向对象思想封装轮播图组件

    原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能 ...

  3. 读书笔记-你不知道的JS中-promise

    之前的笔记没保存没掉了,好气,重新写! 填坑-- 现在与将来 在单个JS文件中,程序由许多块组成,这些块有的现在执行,有的将来执行,最常见的块单位是函数. 程序中'将来'执行的部分并不一定在'现在'运 ...

  4. js:基于原生js的上啦下啦刷新功能

    链接:https://www.jianshu.com/p/a8392115e6f0演示地址:http://wonghan.cn/iscroll-demo/html:<body> <d ...

  5. underscore.js学习笔记

    一.理清概念 1.Underscore封装了常用的JavaScript对象操作方法,用于提高开发效率,Underscore还可以被使用在Node.js运行环境.从API中,你已经可以看出,Unders ...

  6. Underscore.js实用插件

    Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象. 他解决了这个问题:“如果我面对一个空白的 HTML ...

  7. JavaScript (JS)基础:DOM 浅析 (含数组Array、字符串String基本方法解析)

    ①文本对象document: 例如:document.getElementById()    只获取一个对象          document.getElementsByTagName()   获取 ...

  8. 原生JS实现动画函数的封装

    封装了一个JS方法,支持元素的基本动画:宽.高.透明度...等,也支持链式动画和同时运动. 获取元素的属性的函数并进行了兼容性处理: function getStyle(obj, attr) { if ...

  9. js实现完整轮播

    1.封装一个简单的动画函数 function animate(obj,target,callback){ clearInterval(obj.timer);//清除定时器防止定时器重复添加 obj.t ...

随机推荐

  1. JAVA读取propertise配置文件

    java中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是"key=value"的格式,在pr ...

  2. UIlabel添加背景图片

    做UI的时候我们可能想给某个Label添加一个背景图片,但查看的时候会发现好像只有设置背景颜色的方法,不过我们也可以通过这种方式来解决: UIColor *color = [UIColor color ...

  3. Unity截图

    什么都不说了,直接上代码. using UnityEngine; using System.Collections; using System.IO; public class CutImage : ...

  4. js——事件

    焦点:使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 我们可以通过一些方式给元素设置焦点 1.点击 2.tab 3.js 不是所有元素都能够接收焦点的.能够响应用 ...

  5. the jar file rt.jar has no source attachment

    解决方法:rt的source在jdk目录的src.zip文件里,找到jdk目录下的src.zip,添加就行了.

  6. node to traverse cannot be null!

    严重: Servlet.service() for servlet springmvc threw exception java.lang.IllegalArgumentException: node ...

  7. c++常用IDE

    vs2013. CodeLite (c/c++/PHP) codeBlocks Qt Creator Xcode

  8. mysql--自动增长

    create table teacher( t_id int primary key auto_increment, #auto_increment 自动增长 需要整型,还需要索引 t_name va ...

  9. swift和objc之對比

    http://mobidev.biz/blog/swift_how_we_code_your_ios_apps_twice_faster

  10. MySql: Column 'XXXX' in field list is ambiguous 错误

    [Err] 1052 - Column 'XXXX' in field list is ambiguous 例如: SELECT id, a.name, price, `describe`, scho ...