上个周日,介绍了如何使用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,有机会我会补充一下,大家也可以畅所欲言,看看有什么其他更好的方法来对付这种循环耗时操作!

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

标签:
settimeout

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“js中setTimeout的妙用--防止循环超时”
暂无“js中setTimeout的妙用--防止循环超时”评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。