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. node.js常见错误及解决办法

    1.npm express命令行下不能执行 解决办法: 4版本需要安装express-generatorc才能使用express命令npm install -g express-generatorwh ...

  2. api (二) 创建控件 (转)

    在Win32 SDK环境下,怎么来创建常用的那些基本控件呢?我们知道如果用MFC,简单的拖放即可完成大多数控件的创建,但是我们既然是用Windows SDK API编程,当然是从根上解决这个问题,实际 ...

  3. poj2891--扩展欧几里德算法

    /* 该题使用的是扩展欧几里德算法,求模线性同余方程: 分析题目:以题目输出结果为例 ,要求得到一个整数X可以满足 X % a = r,a,r,为数组名: 设数组元素为两个时, 列出方程:X % a1 ...

  4. hdu 4639 Hehe (dp)

    一道dp题,转移方程不是自己推出来的. 题目的意思是用‘qnmlgb’替换‘hehe’,可以替换也可以不替换,问有多少种情况. 如果结尾不是‘hehe’,那么dp[i]=dp[i-1],如果是是‘he ...

  5. 关于 css padding 的使用 padding会将使用该属性的元素撑开

    .right_img_box{ width:300px; height:250px; border:1px solid #c9c9c9; margin-bottom:15px; background: ...

  6. Python你必须知道的十个库

    Python是优雅的,使用这些库可以使你的代码更简洁,并保持持久性.欢迎各位补充,并提出意见! Docopt.抛弃optparse和argparse吧,使用docstrings来构建优雅的,可读性强的 ...

  7. php程序员的弱点

    今天在在知乎上看到一个问题,题目是<看了laravel的php框架怎么感觉很不靠谱?>,我最近也在想学习一下laravel,laravel听说是受到很大ruby on rails的影响. ...

  8. hdu 5724 Chess 博弈

    题目链接 一个n行20列的棋盘. 每一行有若干个棋子. 两人轮流操作, 每人每次可以将一个棋子向右移动一个位置, 如果它右边有一个棋子, 就跳过这个棋子, 如果有若干个棋子, 就将这若干个都跳过. 但 ...

  9. Eclipse 修改编码格式

    在Eclipse的开发使用中,我们经常使用的是UTF-8,但是刚刚安装的或者是导入的项目是其他编码的默认是GBK的,这就造成我们的项目乱码,一些中文解析无法查看,对我们的开发造成不便. 修改工作空间默 ...

  10. python初学笔记(三)

    Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节 (byte),所以,一 ...