您现在的位置:首页 >> 前端 >> 内容

浅谈setTimeout,setInterval

时间:2017/8/29 11:28:00 点击:

  核心提示:概念setTimeoutsetTimeout的用法var timer1=scope.setTimeout(function,[delay,params]);var timer2=scope.setTi...

概念

setTimeout

setTimeout的用法

var timer1=scope.setTimeout(function,[delay,params]);
var timer2=scope.setTimeout(code,[delay,params]);
function
function 是你想要在delay毫秒之后执行的函数。 code
第二种语法,是指你想要在delay毫秒之后执行的代码字符串 (使用该语法是不推荐的, 不推荐的原因和eval()一样)。 delay 可选
延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生。如果省略该参数,delay取默认值0。实际的延迟时间可能会比 delay 值长,原因请查看Reasons for delays longer than specified。 param1, …, paramN 可选
可选参数。

参考:
https://jeffjade.com/2016/01/10/2016-01-10-javacript-setTimeout/

用字符串的问题:

推迟执行的代码以字符串的形式,放入setTimeout,因为引擎内部使用eval函数,将字符串转为代码;

    setTimeout('console.log("2")', 1000)

这段代码在浏览器环境中会运行,在nodeJS环境中会报错;这里规定了setTimeout只能是函数;
浅谈setTimeout,setInterval

不推荐使用字符串的原因,因为不推荐使用eval:

eval() 是一个危险的函数, 他执行的代码拥有着执行者的权利。如果你用eval()运行的字符串代码被恶意方(不怀好意的人)操控修改,您可能会利用最终在用户机器上运行恶意方部署的恶意代码,并导致您失去您的网页或者扩展程序的权限。更重要的是,第三方代码可以看到某一个eval()被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的Function就是不容易被攻击的。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCgk8cD5ldmFsKCm1xNTL0NDQp8LK0rLG1bHptcSxyMbky/u1xMzmtPq3vbC4wv2jrNLyzqrL+7vhtffTw2pzveLO9sb3o6y8tLHjz9a0+rXESlPS/cfm1tDS0b6tttS0y9f2wcvTxbuvoaM8L3A+DQo8L2Jsb2NrcXVvdGU+DQo8cD5zZXRUaW1lb3V0tcTX99PDo7o8YnIgLz4NCjEuILX31fvKwrz+tcTLs9Dyo7s8YnIgLz4NCjIuIGFqYXi3wLa2tq88YnIgLz4NCjMuILfWuO66xMqxyM7O8TwvcD4NCjxoMiBpZD0="setinterval">setInterval

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和内存使用量。

Tags:浅谈 谈S SE ET 
作者:网络 来源:Daisy花园
  • 上一篇:EL表达式详解
  • 下一篇:css3贝塞尔曲线