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 相关文章推荐
javascript 必知必会之closure
Sep 21 Javascript
jquery.bgiframe.js在IE9下提示INVALID_CHARACTER_ERR错误
Jan 11 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
May 09 Javascript
用JS实现轮播图效果(二)
Jun 26 Javascript
移动端使用localStorage缓存Js和css文的方法(web开发)
Sep 20 Javascript
详解vue前后台数据交互vue-resource文档
Jul 19 Javascript
Three.js入门之hello world以及如何绘制线
Sep 25 Javascript
Vue2 配置 Axios api 接口调用文件的方法
Nov 13 Javascript
基于wordpress的ajax写法详解
Jan 02 Javascript
Vue-cli项目部署到Nginx服务器的方法
Nov 01 Javascript
vue.js路由mode配置之去掉url上默认的#方法
Nov 01 Javascript
vue 动态生成拓扑图的示例
Jan 03 Vue.js
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 文件上传全攻略
2010/04/28 PHP
PHP中fwrite与file_put_contents性能测试代码
2013/08/02 PHP
Extjs TimeField 显示正常时间格式的代码
2011/06/28 Javascript
JQuery设置和去除disabled属性的5种方法总结
2013/05/16 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
详解利用exif.js解决ios手机上传竖拍照片旋转90度问题
2016/11/04 Javascript
node.js基于mongodb的搜索分页示例
2017/01/22 Javascript
基于Bootstrap的网页设计实例
2017/03/01 Javascript
微信小程序之电影影评小程序制作代码
2017/08/03 Javascript
如何理解Vue的v-model指令的使用方法
2018/07/19 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
Vue和React组件之间的传值方式详解
2019/01/31 Javascript
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
vue项目打包上传github并制作预览链接(pages)
2019/04/19 Javascript
Vue 指令实现按钮级别权限管理功能
2019/04/23 Javascript
Python常用随机数与随机字符串方法实例
2015/04/09 Python
python类中super()和__init__()的区别
2016/10/18 Python
Python3利用SMTP协议发送E-mail电子邮件的方法
2017/09/30 Python
python3库numpy数组属性的查看方法
2018/04/17 Python
Python使用ctypes调用C/C++的方法
2019/01/29 Python
python实现二分类和多分类的ROC曲线教程
2020/06/15 Python
在keras里实现自定义上采样层
2020/06/28 Python
CSS3 文字动画效果
2020/11/12 HTML / CSS
NUK奶瓶美国官网:NUK美国
2016/09/26 全球购物
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
幼儿园运动会入场词
2014/02/10 职场文书
小学三好学生事迹材料
2014/08/15 职场文书
大型公益活动策划方案
2014/08/20 职场文书
教师节感谢信
2015/01/22 职场文书
部门经理助理岗位职责
2015/04/13 职场文书
讲座开场白台词和结束语
2015/05/29 职场文书
保外就医申请书范文
2015/08/06 职场文书
解析CSS 提取图片主题色功能(小技巧)
2021/05/12 HTML / CSS
详解MySQL的Seconds_Behind_Master
2021/05/18 MySQL
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
python保存图片的四个常用方法
2022/02/28 Python