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. iOS 网络请求——post请求

    -(void)postRequest{ NSString *urlString = [NSString stringWithFormat:@"http://f1.netgears.cn:80 ...

  2. 20151120 jsp相关

    jsp 声明表示.代码片段及引用 <%@ page language="java" contentType="text/html; charset=UTF-8&qu ...

  3. binaryTree:普通二叉树

    #ifndef _Tree_H #define _Tree_H typedef int ElementType; typedef struct TreeNode { ElementType Eleme ...

  4. java泛型问题 关于警告:XX is a raw type

    (本文例子适用于JDK 5.0, 学习请先安装并配置!!!)         我们从一个简单的例子开始:假设我们现在需要一个专用来存储字符串的List,该如何实现?呵呵,这还不简单,且看如下代码:   ...

  5. JavaWeb基础之tomcat部署

    有些东西,看起来简单,做起来也简单,简单的你并不一定知道! 问题:如何将一个java project转变为 web project,并使其自动部署到tomcat? 1.先建立一个Java Projec ...

  6. 编写一个程序实现strcpy函数的功能

    #include <stdio.h> #include <string.h> #define N 5 char *mycpy(char *s1, char *s2) { //数 ...

  7. Trafic

    Dialogue 1  You took the wrong bus 你做错车了 A:Hi, I want to see the Terra Cotta Warriors in Xi'an. Coul ...

  8. win7_32位安装MySQL_5.6以及密码修改方法

    1.下载mysql: http://www.xiazaiba.com/html/361.html 2.安装 方便起见,全部默认下一步吧,原理一个样,最后安装到: 3.配置环境变量 我这里添加的是  C ...

  9. 剑指offer——已知二叉树的先序和中序排列,重构二叉树

    这是剑指offer中关于二叉树重构的一道题.题目原型为: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2, ...

  10. openNebula dubug

    lowest common denominator convenient way to manage virtual machines