上周日,我介绍了如何使用setTimeout代替setInterval进行间歇呼叫。本周日,我将继续讲述setTimeout在《JavaScript高级程序设计》,——这本书里的另一个妙用,防止循环超时
【这是在为故事的高潮做铺垫】
JS是单线程的,代码块中的代码只能从上到下依次执行。因此,如果中间有代码,执行起来会花很多时间,导致后面的代码无法执行,浏览器就会挂起。
JS有两种常见的耗时操作:1。向服务器发起请求;2.循环一个数组(当然还有一个结合了1和2的,叫做循环操作向服务器发送请求,哈哈哈,实际项目中人们经常这么做)
解决这两个耗时操作的思路是一样的:——异步编程。JS的异步编程不是多线程,因为如上所述,JS是单线程的。异步JS直观理解为延迟和回调。
对于第一种耗时的情况,我们使用ajax异步请求,并在耗时的请求返回结果时回调。
对于第二种耗时的情况,本文将介绍的方法setTimeout延迟调用可用于数组块处理。
[这是高潮]
假设我们要处理一个大小为100的数组。对于数组中的每个元素,我们需要进行大量的处理,每个元素需要1s左右的处理时间;
我们认为程序背后的代码不会依赖于我们对这个数组的处理结果。
下面的代码用两种方式处理这个数组,一种是常规方式,另一种是setTImeout的数组块处理
var process time=0;//常规操作tcCircle();//注释上面的代码并释放下面的注释来执行setTimeout数组阻塞操作///tcCircleUseSetTimeout();//耗时的circle function tcCircle(){ var arr=new Array(100);for(var I=0;长度;I){ process(arr[I]);}//页面标题栏不停打转,以下语句无法长时间执行console.log('重要进程');console.log('finish!');}函数tcCircleUseSetTimeout(){ var arr=new Array(100);setTimeout(function(){ var ele=arr . shift();过程(ele);if(arr . length 0){ setTimeout(arguments . callee,100);} },100);console.log('重要进程');console.log('finish!');}函数process(ele){ console . log(' process '(process time));//模拟长时间处理睡眠(1000);}功能睡眠(sleepTime){ var start=new Date()。getTime();while(true){ if(new Date()。getTime()-startsleep time){ break;}}}首先,我们执行常规操作。因为是单线程,可以想象执行这个程序至少需要1*100=100s,浏览器会造假。
然后我们执行setTimeout的方法。我们一次只操作数组中的一个对象,每次操作之间设置100毫秒的延迟,让js引擎执行主干代码。所以很明显执行效果很好!
我们可以看到,不仅浏览器的标题栏不会变成菊花,控制台还会快速打印出我们在代码后面打印的语句,表示主程序已经完成,数组处理定期执行。
通过这样的优化,我们的程序给用户的体验提供了很多提示。当然,这只是书中介绍的一种方法。我相信还有很多其他方法可以实现它。比如我现在能想到承诺。有机会我再补充。大家可以畅所欲言,看看还有什么更好的方法来应对这个周期和耗时的操作!
以上就是本文的全部内容。希望本文的内容能给大家的学习或工作带来一些帮助,也希望多多支持我们!