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优缺点分析说明
Apr 10 Javascript
Microsfot .NET Framework4.0框架 安装失败的解决方法
Aug 14 Javascript
ExtJS4 动态生成的grid导出为excel示例
May 02 Javascript
javascript版2048小游戏
Mar 18 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
Dec 16 Javascript
Angular在模板驱动表单中自定义校验器的方法
Aug 09 Javascript
vue 组件中slot插口的具体用法
Apr 03 Javascript
JavaScript常用截取字符串的三种方式用法区别实例解析
May 15 Javascript
Vue模板语法中数据绑定的实例代码
May 17 Javascript
IE11下处理Promise及Vue的单项数据流问题
Jul 24 Javascript
JavaScript自定义超时API代码实例
Apr 30 Javascript
动态规划之使用备忘录来改进Javascript函数
Apr 07 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实现mysql封装类示例
2014/05/07 PHP
yii2 resetful 授权验证详解
2017/05/18 PHP
ThinkPHP6.0如何利用自定义验证规则规范的实现登陆
2020/12/16 PHP
Jquery 动态添加按钮实现代码
2010/05/06 Javascript
Jquery中获取iframe的代码
2011/01/11 Javascript
javascript跑马灯悬停放大效果实现代码
2012/12/12 Javascript
JS实现两表格里数据来回转移的方法
2015/05/28 Javascript
jquery购物车结算功能实现方法
2020/10/29 Javascript
jQuery实现QQ空间汉字转拼音功能示例
2017/07/10 jQuery
js将键值对字符串转为json字符串的方法
2018/03/30 Javascript
vue 路由嵌套高亮问题的解决方法
2018/05/17 Javascript
Vue组件全局注册实现警告框的实例详解
2018/06/11 Javascript
微信小程序ibeacon三点定位详解
2018/10/31 Javascript
在vue项目中使用Jquery-contextmenu插件的步骤讲解
2019/01/27 jQuery
vue自定义指令directive的使用方法
2019/04/07 Javascript
小程序中this.setData的使用和注意事项
2019/08/28 Javascript
JavaScript进阶(四)原型与原型链用法实例分析
2020/05/09 Javascript
[03:40]DOTA2英雄梦之声_第01期_炼金术士
2014/06/23 DOTA
[39:00]Optic vs VP 2018国际邀请赛淘汰赛BO3 第三场 8.24
2018/08/25 DOTA
Python验证码识别的方法
2015/07/10 Python
Python多进程multiprocessing用法实例分析
2017/08/18 Python
Django web框架使用url path name详解
2019/04/29 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
2019/12/04 Python
python清空命令行方式
2020/01/13 Python
python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例
2020/03/08 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
2020/09/16 Python
CSS类名支持中文命名的示例
2014/04/04 HTML / CSS
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
Kipling凯浦林美国官网:世界著名时尚休闲包袋品牌
2016/08/24 全球购物
瑞典时尚服装购物网站:Miinto.se
2017/10/30 全球购物
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
2014/07/27 面试题
甜品店创业计划书
2014/09/21 职场文书
电子银行业务授权委托书
2014/10/10 职场文书
毕业生爱心捐书倡议书
2015/04/27 职场文书
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android
如何使用python包中的sched事件调度器
2022/04/30 Python