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. EC读书笔记系列之8:条款13、14、15

    条款13 以对象管理资源 记住: ★为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放 ★两个常被使用的RAII classes分别是tr1::shared_ptr和aut ...

  2. stat 函数讲解

    表头文件:    #include <sys/stat.h>                     #include <unistd.h>定义函数:    int stat( ...

  3. jquery 学习笔记二 隐藏与显示

    css找到元素后是添加样式,而jquery找到元素后是添加形为. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...

  4. 使用javascript把图片转成base64位编码,然后传送到服务端(ajax调用的接口基于drupa7)

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. mysql错误提示不是英语的解决办法

    mysql提示突然就变成法语了,google了一下,找到了解决方法:打开my.ini文件,找到[mysqld]配置项如下 [mysqld] port explicit_defaults_for_tim ...

  6. 引用(ajaxfileupload.js) ajaxfileupload.js报这错jQuery.handleError is not a function

    jQuery.handleError is not a function 原因是,经测试handlerError只在jquery-1.4.2之前的版本中存在,jquery-1.6 和1.7中都没有这个 ...

  7. J2SE知识点摘记(二十四)

     覆写hashCode() 在明白了HashMap具有哪些功能,以及实现原理后,了解如何写一个hashCode()方法就更有意义了.当然,在HashMap中存取一个键值对涉及到的另外一个方法为equa ...

  8. 一个在mac上编译c++程序的低级失误

    今天在编译hadoop的pipes的wordcount例子时,总是报错不能成功. g++ -m64 -I/Users/stephen/Downloads/hadoop-0.20.2/c++/Mac_O ...

  9. Make Hadoop 1.2.1 run, my first try

    经历两天努力,8月25日下午2点40分,终于让hadoop1.2.1跑起来. 用的是<Hadoop实战第2版>(陆嘉恒)里面的WordCount例子,虽然书是2013年出的,但用的例子还是 ...

  10. js笔记-DOM基础

    DoM 浏览器支持: IE: 10% FF: 99% Chrome: 60% childNotes不兼容 在Chrome和IE9中会将文本节点也算作childNotes,而在IE6-8中childNo ...