setTimeout的妙用2——防止循环超时
上个周日,介绍了如何使用setTimeout代替setInterval进行间歇调用,这个周日,继续来讲《JavaScript高级程序设计》这本书里面,对于setTimeout的另一种妙用——防止循环超时
【这是铺垫,为故事的高潮埋下伏笔】
JS是单线程的,一个代码块里面的代码,只能按顺序从上到下执行,所以如果中间有一块代码,执行起来非常耗时,就会导致下面的代码无法执行,出现浏览器假死的状态。
JS的耗时操作,常见的有两种 1.向服务器发起请求 2.对数组的循环操作 (当然,还有一种,就是把1和2合在一起,叫做 在循环操作里面向服务器发出请求,哈哈哈,实际项目里面经常有人这么干)
解决这两种耗时操作的思路都是一样的——异步编程。JS的异步编程,并不是多线程,因为正如上面所说的,JS是单线程的。JS的异步,直观上的理解,就是延时和回调。
对于第一种耗时情况,我们采用的是ajax异步请求,待耗时的请求返回结果时,进行回调操作。
对于第二种耗时情况,则可以使用本文即将介绍的方法,setTimeout延时调用,进行数组分块处理。
【这才是高潮】
假设我们要处理一个大小为100的数组,对于数组中每个元素,都需要执行大量的处理,每个元素大约需要1s的处理时间;
并且我们认为,程序后面的代码,不会依赖于我们对这个数组的处理结果。
于是就有了下面这段代码,以两种方式来处理这个数组,一种是常规方式,一种是setTImeout的数组分块处理
var processTime = 0; //常规操作
tcCircle();
//注释上面的代码 放开下面注释 以执行setTimeout数组分块操作
//tcCircleUseSetTimeout(); //time consuming circle
function tcCircle(){
var arr = new Array(100);
for(var i=0;i<arr.length;i++){
process(arr[i]);
}
//页面标题栏一直转圈 且下面的语句迟迟无法执行
console.log("important process");
console.log("finish!");
} function tcCircleUseSetTimeout(){
var arr = new Array(100);
setTimeout(function(){
var ele = arr.shift();
process(ele);
if(arr.length>0){
setTimeout(arguments.callee,100);
}
},100);
console.log("important process");
console.log("finish!");
} function process(ele){
console.log("process"+(++processTime));
//模拟长时间的处理过程
sleep(1000);
} function sleep(sleepTime){
var start=new Date().getTime();
while(true){
if(new Date().getTime()-start>sleepTime){
break;
}
}
}
首先我们执行常规的操作,由于是单线程,可想而知,执行完这段程序,至少要 1*100 = 100s,并且浏览器会出现假死

然后我们执行setTimeout方式的方法,setTImeout的方式,我们每次只操作数组里面的一个对象,并且在每次操作之间,设置了100ms的延时,供js引擎执行主干的代码,因此,很明显,执行的效果非常棒!

我们看到,不仅浏览器的标题栏不会转菊花了,控制台也很快就打印出 我们在代码最后面打印的语句,说明主干程序已经走完,数组的处理则定时执行着。
通过这样的优化,我们的程序给用户的体验提示了许多,当然,这里只是书中介绍的一种方法,我相信还有很多其他实现方式,比如我现在可以想到的就有promise,有机会我会补充一下,大家也可以畅所欲言,看看有什么其他更好的方法来对付这种循环耗时操作!
setTimeout的妙用2——防止循环超时的更多相关文章
- 前端开发:setTimeout与setInterval 定时器与异步循环数组
前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的, ...
- 关于setTimeout的妙用
定义 在指定的延迟时间之后调用一个函数或执行一个代码片段 这个是setTimeout最主要的功能,但也是很坑的地方,首先javascript其实是运行在单线程的环境下,意味者定时器会在未来的某个时间支 ...
- 关于setTimeout的妙用前端函数节流
最近在某团队忙于一个项目,有这么一个页面,采用传统模式开发(吐槽它为什么不用React),它的DOM操作比较多,然后性能是比较差的,尤其当你缩放窗口时,可怕的事情发生了,出现了卡顿,甚至浏览器瘫痪.为 ...
- JS实现停留几秒sleep,Js中for循环的阻塞机制,setTimeout延迟执行
//第一种,使用while循环 function sleep(delay) { var start = (new Date()).getTime(); while((new Date()).getTi ...
- JS中For循环中嵌套setTimeout()方法的执行顺序
在For循环中执行setTimeOut()方法的代码,执行顺序是怎样的呢? 代码如下 function time() { for(var i= 0;i<5;i++){ setTimeout(fu ...
- 闭包应用之延迟函数setTimeout
根据HTML 5标准,setTimeout推迟执行的时间,最少是5毫秒.如果小于这个值,会被自动增加到5ms. 每一个setTimeout在执行时,会返回一个唯一ID,把该ID保存在一个变量中,并传入 ...
- setTimeout的小尴尬
我们都知道,alert这种内置弹框会阻塞后续代码执行: 之所以如此,就是因为JavaScript代码在浏览器中是单线程执行的.换句话说,浏览器中只有一个主线程负责运行所有JavaScript代码(不考 ...
- setTimeout和setInterval从入门到精通
我们在日常web前端开发中,经常需要用到定时器方法. 前端中的定时器方法是浏览器提供的,并不是ECMAScript规范中的.是window对象的方法. 浏览器中的定时器有两种, 一种是每间隔一定时间执 ...
- setTimeout与取号机之间的关系
说到setTimeout写过javascript的伙伴们一定不会陌生,去银行办过存取款业务的伙伴一定对取号机不会陌生.今天群里有个好伙伴在问setTimeout的问题,大伙你一言我一语,讲了很多,可是 ...
随机推荐
- 字符集UTF-8MB4 MySQL utf8mb4 字符集,用于存储emoji表情
字符集UTF-8MB4 utf8mb4兼容utf8,且比utf8能表示更多的字符.看unicode编码区从1 - 126就属于传统utf8区,当然utf8mb4也兼容这个区,126行以下就是utf8m ...
- MVC 与 MVVM
MVC View直接访问Model,View包含Model信息,包括业务逻辑. MVC模型里Model不变,Model不依赖于View,但是 View依赖于Model.因为View实现了一些业务逻辑, ...
- 网站环境apache + php + mysql 的XAMPP,如何实现一个服务器上配置多个网站?
xampp 是一个非常方便的本地 apache + php + mysql 的调试环境,在本地安装测试 WordPress 等各种博客.论坛程序非常方便.今天我们来给大家介绍一下,如何使用 XAMPP ...
- 简单的shared_ptr实现
RT,代码参考了STL中shard_ptr的实现,基本原理是引用计数,利用Ref_cnt类来管理内存,在shared_ptr创建时创建,此后shared_ptr仅是在拷贝复制析构的过程中对引用进行修改 ...
- Selenium2(java)定位页面元素 二
辅助工具: chrome浏览器,F12打开控制台; Firefox浏览器,F12打开控制台; 或者选中要定位的元素右键 安装firefox扩展firebug和firepath; 安装之后F12可调用f ...
- Java 获取url参数
1. 方式一:使用HttpServletRequest对象 String id = arg0.getParameter("id"); mv.addObject("id&q ...
- 决策树ID3算法
决策树 (Decision Tree)是在已知各种情况发生概率的基础上,通过构成 决策树 来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法 ...
- JQuery hover toggle事件使用
JQuery hover toggle事件使用: <%@ page language="java" import="java.util.*" pageEn ...
- 手机APP测试思路及测试要点
一 手机APP测试基本思路: 测试计划--测试方案--测试用例--执行: 很多小公司都没有具体的需求,项目时间也比较紧,而且流程也不是很严谨,在这样的情况之下,作为测试的我们,该怎样去对项目进行用例 ...
- Android 自定义通用的loadingview
介绍 好久没有写博客啦,最近在接近新年了,年前的工作都要收尾,所以特别忙,周末抽空写了个通用的加载view,写篇博客分享出来. 功能 1.显示加载视图,加载失败的时候显示加载失败视图,数据为空时显示数 ...