数组分块

所谓数组分块,就是当你发现某个循环占用了大量时间,同时对于上述两个问题,你的回答都是“否”,那么你就可以使用定时器分割这个循环。

思路是结合定时器进行递归调用定时器

基本示例如下:

setTimeout(function(){//取出下一个条目并处理var item = array.shift();process(item);//若还有条目,再设置另一个定时器if(array.length > 0){setTimeout(arguments.callee, 100);}
}, 100);

封装成函数如下:

function chunk(array, process, context){setTimeout(function(){var item = array.shift();process.call(context, item);if (array.length > 0){setTimeout(arguments.callee, 100);}}, 100);
}

chunk()方法接受三个参数:要处理的项目的数组,用于处理项目的函数,以及可选的运行该函数的环境。函数内部用了之前描述过的基本模式,通过call()调用的process()函数,这样可以设置一个合适的执行环境(如果必须)。定时器的时间间隔设置为了 100ms,使得 JavaScript进程有时间在处理项目的事件之间转入空闲。你可以根据你的需要更改这个间隔大小,不过100ms在大多数情况下效果不错。可以按如下所示使用该函数:

var data = [12,123,1234,453,436,23,23,5,4123,45,346,5634,2234,345,342];
function printValue(item){var div = document.getElementById("myDiv");div.innerHTML += item + "<br>";
}
chunk(data, printValue);

什么场景用?

数组分块 一般用于什么场景呢?一般用于耗时比较长的循环时,以防脚本长时间运行,导致浏览器崩溃

还有一种方法是吧数组以8为基数,0-8为一组,9-16为一组,以此类推,然后循环,这里里面的8个依次调用,只需要循环外面的大块,也能进行优化

函数节流

什么是函数节流?

某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。

函数节流的基本模式如下:

var processor = {timeoutId: null,//实际进行处理的方法performProcessing: function(){//实际执行的代码},//初始处理调用的方法process: function(){clearTimeout(this.timeoutId);var that = this;this.timeoutId = setTimeout(function(){that.performProcessing();}, 100);}
};
//尝试开始执行
processor.process();

简化以后:

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

函数节流的作用是在高频率得调用一个函数时,最终只会在停止触发后调用一次函数,能节省操作成本,和优化性能

自定义事件

事件,什么是事件?

事件是一种叫做观察者的设计模式,这是一种创建松散耦合代码的技术。对象可以发布事件,用来表示在该对象生命周期中某个有趣的时刻到了。然后其他对象可以观察该对象,等待这些有趣的时刻到来并通过运行代码来响应。

观察者模式:

观察者模式由两类对象组成:主体和观察者。主体负责发布事件,同时观察者通过订阅这些事件来观察该主体。该模式的一个关键概念是主体并不知道观察者的任何事情,也就是说它可以独自存在并正常运作即使观察者不存在。从另一方面来说,观察者知道主体并能注册事件的回调函数(事件处理程序)。涉及DOM上时,DOM元素便是主体,你的事件处理代码便是观察者。

事件是与 DOM 交互的最常见的方式,但它们也可以用于非 DOM 代码中——通过实现自定义事件。
自定义事件背后的概念是创建一个管理事件的对象,让其他对象监听那些事件。实现此功能的基本模式
可以如下定义:

function EventTarget(){this.handlers = {};
}
EventTarget.prototype = {constructor: EventTarget,addHandler: function(type, handler){if (typeof this.handlers[type] == "undefined"){this.handlers[type] = [];}this.handlers[type].push(handler);},fire: function(event){if (!event.target){event.target = this;}if (this.handlers[event.type] instanceof Array){var handlers = this.handlers[event.type];for (var i=0, len=handlers.length; i < len; i++){handlers[i](event);}}},removeHandler: function(type, handler){if (this.handlers[type] instanceof Array){var handlers = this.handlers[type];for (var i=0, len=handlers.length; i < len; i++){if (handlers[i] === handler){break;}}handlers.splice(i, 1); }}
};

EventTarget 类型有一个单独的属性handlers,用于储存事件处理程序。还有三个方法:addHandler() ,用于注册给定类型事件的事件处理程序;fire(),用于触发一个事件;removeHandler(),用于注销某个事件类型的事件处理程序。

addHandler()方法接受两个参数:事件类型和用于处理该事件的函数。当调用该方法时,会进行一次检查,看看handlers属性中是否已经存在一个针对该事件类型的数组;如果没有,则创建一个新的。然后使用 push()将该处理程序添加到数组的末尾。

如果要触发一个事件,要调用fire()函数。该方法接受一个单独的参数,是一个至少包含 type属性的对象。fire()方法先给event对象设置一个target属性,如果它尚未被指定的话。然后它就查找对应该事件类型的一组处理程序,调用各个函数,并给出 event 对象。因为这些都是自定义事件,所以event对象上还需要的额外信息由你自己决定。

removeHandler()方法是addHandler()的辅助,它们接受的参数一样:事件的类型和事件处理程序。这个方法搜索事件处理程序的数组找到要删除的处理程序的位置。如果找到了,则使用 break操作符退出for循环。然后使用splice()方法将该项目从数组中删除。

使用 EventTarget 类型的自定义事件可以如下使用:

function handleMessage(event){alert("Message received: " + event.message);
}
//创建一个新对象
var target = new EventTarget();
//添加一个事件处理程序
target.addHandler("message", handleMessage);
//触发事件
target.fire({ type: "message", message: "Hello world!"});
//删除事件处理程序
target.removeHandler("message", handleMessage);
//再次,应没有处理程序
target.fire({ type: "message", message: "Hello world!"}); 

JavaScript第二十四篇 高级定时器(下)相关推荐

  1. setitimer 创建两个定时器_JavaScript第二十四篇 高级定时器(下)

    数组分块 所谓数组分块,就是当你发现某个循环占用了大量时间,同时对于上述两个问题,你的回答都是"否",那么你就可以使用定时器分割这个循环. 思路是结合定时器进行递归调用定时器 基本 ...

  2. 【正点原子MP157连载】第二十四章 设备树下的LED驱动实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  3. slim php dd model,第二十四节,TensorFlow下slim库函数的使用以及使用VGG网络进行预训练、迁移学习(附代码)...

    在介绍这一节之前,需要你对slim模型库有一些基本了解,具体可以参考第二十二节,TensorFlow中的图片分类模型库slim的使用.数据集处理,这一节我们会详细介绍slim模型库下面的一些函数的使用 ...

  4. 第二十四篇:可靠信号机制

    前言 曾经的 UNIX 系统中,信号的不可靠的.什么是不可靠?就是信号丢失呗.那什么是信号丢失?就是当系统正在处理某个事务的时候,如果收到了某个信号,但它不能及时处理这个信号,那么只能忽略掉此信号. ...

  5. Python之路【第二十四篇】Python算法排序一

    什么是算法 1.什么是算法 算法(algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出.简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果. ...

  6. 【Java成王之路】EE初阶第二十四篇: Servlet

    Sevlet Servlet 是什么 Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一 个 web app. Tomcat 是一个 ...

  7. SpringBoot第二十四篇: springboot整合docker

    这篇文篇介绍,怎么为 springboot程序构建一个docker镜像.docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源.Docker 可以让开发者打包他们的 ...

  8. Scala入门到精通——第二十四节 高级类型 (三)

    本节主要内容 Type Specialization Manifest.TypeTag.ClassTag Scala类型系统总结 在Scala中,类(class)与类型(type)是两个不一样的概念. ...

  9. 第二十四篇 -- 学习第二十九天打卡20190720

    学习书籍<剑桥商务英语中级词汇精选>乱序版 Day05 Day25spectrum ['spektrəm] n.范围:领域:光谱:声谱例:This large group of resea ...

最新文章

  1. 理解__repr__
  2. android viewpager动态加载图片,Android使用ViewPager加载图片和轮播视频
  3. WCF Data Services 基础
  4. MATLAB用递归法求解集合子集,用递归法求一个集合的子集c语言,急!!!
  5. Spring对不同来源的Resources的支持
  6. 为5—18岁青少年提供营地教育,漫族完成百万级天使轮融资
  7. 去雾综述_图像去雾的算法历史与综述
  8. 20.从0开始的微服务架构
  9. animate.css做点赞效果
  10. VB编程操作AutoCAD线型
  11. c语言编程软件平板_ipad可以编程c语言吗
  12. MITO-ID 线粒体膜电位检测试剂盒的作用机制和应用
  13. IDEA - 如何安装Statistic代码统计插件?
  14. color-scheme 属性根据操作系统配色方案调整页面样式
  15. 高阶数据结构 —— 红黑树(较平衡搜索树)
  16. android11.0 Launcher3 高端定制之循环滑动
  17. 算法题库与在线刷题网站推荐
  18. Mac Carthage
  19. 使用C#解逻辑题:小王、小张、小赵三个人是好朋友,他们中间其中一个人下海经商,一个人考上了重点大学,一个人参军了。此外他们还知道以下条件:小赵的年龄比士兵的大;大学生的年龄比小张小;小王的年龄和大学生
  20. 数论专题笔记(1)——同余,整除,欧拉定理,中国剩余定理

热门文章

  1. 百度卫星地图无法使用鼠标绘制工具的问题简单解决方案
  2. 天津办理测绘资质流程以及要求(转让天津测绘资质)
  3. RT-Thread—FAL与EasyFlash组件移植
  4. coreseek-4.1-win32版本下windows安装记录
  5. Tal Ben-Shahar 积极心理学_课程小结
  6. ssmtp使用阿里企业邮箱发送邮件
  7. wince挂起和唤醒_relayon
  8. 正反馈、负反馈、电容器偶合、直偶、偏置
  9. opensource项目_宣布2018年Opensource.com社区奖获奖者
  10. java实现自动售货机