浅谈setTimeout,setInterval

概念

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 可选
    可选参数。

参考:
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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值