setTimeout的用法
var timer1=scope.setTimeout(function,[delay,params]);
var timer2=scope.setTimeout(code,[delay,params]);
参考:
http://jeffjade.com/2016/01/10/2016-01-10-javacript-setTimeout/
用字符串的问题:
推迟执行的代码以字符串的形式,放入setTimeout,因为引擎内部使用eval函数,将字符串转为代码;
setTimeout('console.log("2")', 1000)
这段代码在浏览器环境中会运行,在nodeJS环境中会报错;这里规定了setTimeout只能是函数;
不推荐使用字符串的原因,因为不推荐使用eval:
eval() 是一个危险的函数, 他执行的代码拥有着执行者的权利。如果你用eval()运行的字符串代码被恶意方(不怀好意的人)操控修改,您可能会利用最终在用户机器上运行恶意方部署的恶意代码,并导致您失去您的网页或者扩展程序的权限。更重要的是,第三方代码可以看到某一个eval()被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的Function就是不容易被攻击的。
eval()的运行效率也普遍的比其他的替代方案慢,因为他会调用js解析器,即便现代的JS引擎中已经对此做了优化。
setTimeout的作用:
1. 调整事件的顺序;
2. ajax防抖动
3. 分割耗时任务
setInterval的用法
let intervalID = window.setInterval(func, delay[, param1, param2, ...]);
let intervalID = window.setInterval(code, delay);
和setTimeout的参数类似,delay是指多少秒之后循环执行函数,同样的不推荐使用code;
setInterval指定的是“开始执行”之间的间隔,并不考虑每次任务执行本身所消耗的事件。因此实际上,两次执行之间的间隔会小于指定的时间。比如,setInterval指定每100ms执行一次,每次执行需要5ms,那么第一次执行结束后95毫秒,第二次执行就会开始。如果某次执行耗时特别长,比如需要105毫秒,那么它结束后,下一次执行就会立即开始。
因此就会出现下面这个问题
var i = 1;
var timer = setInterval(function() {
alert(i++);
}, 2000);
上面这段代码的思路是,每隔2000毫秒,执行弹出框,但是如果第一次弹出了之后,用户没有立即关闭窗口,而是等了好久好久,那么后面的弹出框就会立马弹出来了,显然这不是我们想要的效果;
可以用setTimeout改进它,思路就是在setTimeout里写递归;
function interval(func, wait) {
var interv = function() {
func.call(null);
setTimeout(interv, wait);
};
setTimeout(interv, wait);
}
interval(function() {
console.log(2);
}, 1000);
setInterVal的运行机制:
setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。
setTImeout的运行机制:
setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行
对于setInterval得使用,个人建议是能不用尽量不用。涉及到必须要的定时器,前文已经叙述可以使用两个setTimeout嵌套组合来实现,并且还能规避掉一些问题得发生。涉及到要用它来制作动画( jQuery就使用setInterval来写动画,也是导致其慢原因之一),更建议使用requestAnimationFrame(RAF),或者直接采用CSS来写(如果可以的话)。
requestAnimationFrame比起setTimeout、setInterval的优势主要有两点:
requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
参考:
http://www.jeffjade.com/2016/01/10/2016-01-10-javaScript-setInterval/
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setInterval