js中setTimeout的妙用--防止循环超时


Posted in Javascript onMarch 06, 2017

上个周日,介绍了如何使用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,并且浏览器会出现假死

js中setTimeout的妙用--防止循环超时

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

js中setTimeout的妙用--防止循环超时

我们看到,不仅浏览器的标题栏不会转菊花了,控制台也很快就打印出 我们在代码最后面打印的语句,说明主干程序已经走完,数组的处理则定时执行着。

通过这样的优化,我们的程序给用户的体验提示了许多,当然,这里只是书中介绍的一种方法,我相信还有很多其他实现方式,比如我现在可以想到的就有promise,有机会我会补充一下,大家也可以畅所欲言,看看有什么其他更好的方法来对付这种循环耗时操作!

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
jquery表单验证框架提供的身份证验证方法(示例代码)
Dec 27 Javascript
js获取元素外链样式的方法
Jan 27 Javascript
基于jQuery实现美观且实用的倒计时实例代码
Dec 30 Javascript
Dropzone.js实现文件拖拽上传功能(附源码下载)
Nov 22 Javascript
svg动画之动态描边效果
Feb 22 Javascript
BootStrap表单控件之复选框checkbox和单选择按钮radio
May 23 Javascript
Bootstrap-table自定义可编辑每页显示记录数
Sep 07 Javascript
Vue-CLI3.x 设置反向代理的方法
Dec 06 Javascript
Mint UI组件库CheckList使用及踩坑总结
Dec 20 Javascript
微信小程序wx.request拦截器使用详解
Jul 09 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
Jul 15 Javascript
解决vue 表格table列求和的问题
Nov 06 Javascript
Bootstrap表单简单实现代码
Mar 06 #Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
Mar 06 #Javascript
Js自动截取字符串长度,添加省略号(……)的实现方法
Mar 06 #Javascript
Bootstrap显示与隐藏简单实现代码
Mar 06 #Javascript
jQuery时间验证和转换为标准格式的时间格式
Mar 06 #Javascript
Bootstrap导航中表单简单实现代码
Mar 06 #Javascript
基于JS实现仿百度百家主页的轮播图效果
Mar 06 #Javascript
You might like
遍历指定目录下的所有目录和文件的php代码
2011/11/27 PHP
解析百度搜索结果link?url=参数分析 (全)
2012/10/09 PHP
Laravel 4 初级教程之视图、命名空间、路由
2014/10/30 PHP
PHP抽奖算法程序代码分享
2015/10/08 PHP
thinkphp框架下404页面设置 仅三步
2016/05/14 PHP
php版微信数据统计接口用法示例
2016/10/12 PHP
thinkPHP5 tablib标签库自定义方法详解
2017/05/10 PHP
PHP单元测试框架PHPUnit用法详解
2019/01/23 PHP
10款非常有用的 Ajax 插件分享
2012/03/14 Javascript
跟我学习javascript的严格模式
2015/11/16 Javascript
js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
2016/04/01 Javascript
jquery根据一个值来选中select下的option实例代码
2016/08/29 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
jfinal与bootstrap的登出实战详解
2017/11/27 Javascript
Angular开发实践之服务端渲染
2018/03/29 Javascript
vue移动端路由切换实例分析
2018/05/14 Javascript
vue+axios+promise实际开发用法详解
2018/10/15 Javascript
在vue中使用echars实现上浮与下钻效果
2019/11/08 Javascript
javascript实现时钟动画
2020/12/03 Javascript
[01:43]倾听DOTA2英雄之声 魅惑魔女国服配音鉴赏
2013/06/06 DOTA
深入理解Python中的 __new__ 和 __init__及区别介绍
2018/09/17 Python
Python 实现Numpy中找出array中最大值所对应的行和列
2019/11/26 Python
Python中bisect的用法及示例详解
2020/07/20 Python
英国电动工具购买网站:Anglia Tool Centre
2017/04/25 全球购物
HUGO BOSS美国官方网上商店:世界知名奢侈品牌
2017/08/04 全球购物
体育纪念品、亲笔签名的体育收藏品:Steiner Sports
2020/07/31 全球购物
比较基础的php面试题及答案-编程题
2012/10/14 面试题
XML文档面试题
2015/08/05 面试题
C#如何调用Word并打开一个Word文档
2013/05/08 面试题
会计学生自我鉴定
2014/02/06 职场文书
爸爸的花儿落了教学反思
2014/02/20 职场文书
保险专业大学生职业规划书
2014/03/03 职场文书
股票投资建议书
2014/05/19 职场文书
2015选调生工作总结
2015/07/24 职场文书
Matplotlib可视化之添加让统计图变得简单易懂的注释
2021/06/11 Python
关于MySQL临时表为什么可以重名的问题
2022/03/22 MySQL