JS中计时器setTimeout以及setInterval的使用以及for循环中延迟打印的坑

JS中的函数使用

一、setTimeout

格式:

var intervalID = scope.setTimeout(function[, delay, param1, param2, ...]) // 参数在延时时间到达后,将作为该函数的传参,但是在不同浏览器存在兼容性问题,若需使用需做兼容性处理,具体参考链接1
var intervalID = scope.setTimeout(function[,delay]) 
var intervalID = scope.setTimeout(code[,delay]) // 这里的code为字符串,例如"alert('hello world')",不推荐此方法,有安全风险,,来自MDN网站

delay为需要延迟的时间,单位为毫秒(可选参数,忽略该参数,则delay取默认值0,将立刻执行或尽快执行,实际的延迟时间可能比期待的delay值长;
function为延迟一定时间后执行的函数
链接1

如何在延迟时间到达前停止setTimeout函数执行:

var t = setTimeout(function[,delay]);
       clearTimeout(t); // 停止上面计时器内部函数的执行

功能:通常在延迟一定时间后仅执行一次,但是也可以实现间隔一定时间循环执行的功能
代码实践:
1、延迟3秒弹出一次警示框

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
    setTimeout(alert_Action, 3000);//setTimeout('alert_Action()', 3000);/ setTimeout(alert_Action(), 3000)//这种写法会立即执行
    var alert_Action = function(){
    alert('我将在3秒后弹出');
    }
</script>
</heaad>

<body>
    <h1>JS输出HTML内容</h1>
</body>
</html>

代码执行 结果
在这里插入图片描述
2、间隔1秒打印一次信息
(在函数内部调用自身,就可以实现无限次数执行该函数)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
    var num = 0
    function countNum() {
        console.log('当前的num值为:' + num);
        num++
        setTimeout(countNum, 1000);
    }
    countNum()
</script>
</heaad>
<body>
    <h1>JS输出HTML内容</h1>
</body>
</html>

代码执行结果
在这里插入图片描述
3、间隔一定时间打印一次,指定打印次数
(使用for循环限制执行函数的次数)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
    var num = 0
    function countNum() {
        console.log('当前的num值为:' + num);
        num++
    }
    for(let i = 0;i < 13;i++){
        setTimeout(countNum, 1000 *(i+1));
    }
</script>
</heaad>
<body>
    <h1>JS输出HTML内容</h1>
</body>
</html>

代码执行结果
在这里插入图片描述
4、在学习的过程中意外的发现了一个坑:
js中延迟打印for循环,如果打印的信息是动态改变的,最后打印出来的结果都是同一个,具体见下面的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>  
     for(var i=0 ; i<10; i++) {
         setTimeout(function() {
         console.log(i);
        }, 1000);
        }
</script>
</heaad>
<body>
</body>
</html>

代码执行结果:10个10
但是下面这组代码同样也是延迟打印for循环,却能正确打印我们想要的信息

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
        for (let i = 0; i < 10; i++) {
            (function (i) {
                setTimeout(function () {
                    console.log(i);
                }, 1000);
            })
            (i);
        }
</script>
</heaad>
<body>
</body>
</html>

代码执行结果:0 1 2 3 4 5 6 7 8 9
在这里插入图片描述
导致这种差异的原因是什么呢,于是我就去晚上各种搜索,发现原因如下
1、JS引擎就是以单线程的机制来运行代码,setTimeout()该函数是属于异步执行的,当执行到setTimeout()代码时,会将该函数放在队列中,由专门负责计时的线程开始计时,计时完毕并在同步任务执行结束后,会通知执行代码的线程执行setTimeout()内的代码。在这里for循环一共执行10次,因此队列中依次放了10个待执行的setTimeout函数,执行该函数前for循环已经执行完毕。
2、var 与 let 在for循环中的区别

for(let i = 0;i < 10;i++){ // let 为块级变量,只在for循环内部起作用
    console.log('i',i);
}

当i = 0 和i = 1时声明的变量i是不同的,这里for循环执行结束后,会有10个不同的变量,他们的值分别为0-9

for(var i = 0;i < 10;i++){ // var声明的为全局变量
    console.log('i',i);
}

var 声明的变量是全局变量,在整个脚本中都可以用,for循环每执行一个迭代,i都会重新赋值,并覆盖初值,for循环结束的结果为一个变量 i = 10,队列中10个setTimeout函数内部的i都指向了同一个i ,故最后打印10个10;
而let 声明的为块级变量,只在当前的for循环中有效,并且在for循环中每次迭代let 都是重新创建一个变量,并不会覆盖之前的变量,因此for循环结束后,会有10个变量,它们的值依次为0-9;

这也解释了为什么这两种方式打印for循环时的结果一个是10个10,一个是一次打印0-9
在这里放一下我看的几个文章的链接:
一文看懂JS的异步
在for循环中var和let的区别
在for循环中使用let和var的区别

二、setInterval
格式

var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]);
var intervalID = scope.setInterval(code, delay); // 与setTimeout()相似,该方法存在安全风险,不推荐使用,来自MDN网站

与setTimeout相似,函数内部代码开始执行的时间可能会晚于delay毫秒
setInterval方法可以传递参数,如下面代码所执行的那样

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
        function f() {
            for (let i = 0; i < arguments.length; i++) {
                console.log(arguments[i])
            }
        }
        setInterval(f,1000,'hello world','aaaaaaaaa','bbbbb','ccccc','dddddddd')
</script>
</heaad>
<body>
    <h1>JS输出HTML内容</h1>
</body>
</html>

代码执行结果:每间隔1秒会打印一次 ‘hello world’,‘aaaaaaaaa’,‘bbbbb’,‘ccccc’,‘dddddddd’
在这里插入图片描述
功能:每次调用同一个函数无限循环执行,delay时间已经包含了代码运行时间,也就是相邻两次调用该函数的时间为delay毫秒。
如何结束该函数的执行:

var  intervalID = setInterval(func, delay, [arg1, arg2, ...]);
clearInterval(intervalID) // 停止setInterval的循环执行
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值