JavaScript setTimeout与setInterval用法详解及区别

作者:纸飞机时间:2026-10-25 09:11:14浏览:403

本文详细解析JavaScript中setTimeout和setInterval两个核心时间函数的用法与区别。通过代码示例说明setTimeout的延迟执行特性及异步队列机制,并介绍利用let或闭包解决循环中定时器变量捕获问题的两种方案。同时讲解setInterval的周期性执行与clearInterval清除机制,最后结合HTML DOM操作实现一个包含缓冲逻辑的新年倒计时完整案例。

I. 总述

在JavaScript开发中,setTimeout()和setInterval()是处理时间相关逻辑的两个关键函数。深入理解并掌握这两个函数的使用,对于编写高效、准确的JS代码至关重要,因为它们在实际项目中应用频率极高。

若用一句话概括这两个函数的核心功能,可以表述如下:

setTimeout(): 该函数能够按照设定的时间值延迟执行其中的事件。

setInterval(): 该函数能够按照设定的时间值作为间隔,周期性的执行其中的时间。

上述仅为简要说明,具体细节将在后续章节中展开讲解。

II. setTimeout()函数

首先介绍setTimeout()函数,其基本语法格式如下:

setTimeout(function,times);

该函数结构简洁,主要包含两个参数:一个是待执行的函数(function),另一个是延迟时间值(times,通常为整数)。其中,函数参数指定了延迟后执行的具体逻辑,而时间参数则定义了等待时长。例如,参考以下简单代码:

setTimeout(function(){
    alert("hello,setTimeout()");
}, 1000);

执行上述代码后,浏览器将在延迟1秒(1000毫秒)后弹出一个提示框。注意,时间单位默认为毫秒。

I. 总述

至此,大家可能觉得该函数非常简单。接下来,请观察以下代码片段,猜猜其输出结果是什么:

for (var i = 1; i <= 5; i++) {
    setTimeout(function () {
        alert(i)
    }, 1000)
}

哎,有人要说了,简单啊,这不是输出:1 2 3 4 5 吗?

然而,实际运行结果如下:【点我揭晓】

实际输出的是五个5。造成这一现象的原因是,setTimeout()是一个异步执行函数。通俗来说,回调函数并不会在for循环的每次迭代中立即执行,而是被放入任务队列中。只有当主线程的所有同步代码执行完毕后,才会去执行队列中的异步任务。

因此,当for循环结束时,变量i的值已经变为5。此时执行队列中的五个回调函数,它们读取到的i值均为5,从而弹出五个5。

针对这一问题,这里提供两种解决方案:

1️⃣ 使用关键字let:

for (let i = 1; i <= 5; i++) {
    setTimeout(function () {
        alert(i)
    }, 1000)
}

为什么使用let就能解决问题呢?

实际上,使用let并未改变异步执行的机制,alert()依然是在循环结束后执行。但区别在于,let声明的变量具有块级作用域,每次循环迭代都会创建一个新的i变量绑定。因此,每个回调函数捕获的是对应迭代中i的当前值(即1到5),从而正确输出了预期结果。

2️⃣ 定义一个外部变量:

这种方法是在循环外部定义一个变量(如j),并在每次定时器回调中操作该变量。虽然这依然不改变异步执行的底层机制,但通过手动递增变量值,实现了预期的输出效果。

var j = 1;
for (i = 1; i <= 5; i++) {
    setTimeout(function () {
        alert(j)
        j++;
    }, 1000);
}

第二种做法逻辑更直观,易于理解,在实际项目开发中也更为常用。

III. setInterval()函数

第二个函数setInterval()的用法相对直观,但功能同样强大。我们先查看其使用格式:

setInterval(function,times);

其参数结构与setTimeout()一致,同样接受一个函数和一个时间间隔值。setInterval()会以设定的times为间隔,周期性重复执行function。我们通过一个小例子进行测试:

setInterval(function(){
    alert('hello,setInterval()');
}, 1000);

运行上述代码后,每隔1秒就会弹出一个提示框,显示指定内容。

运行后,大家可能会产生一个疑问:是否可以在特定条件下停止这种循环执行?答案是肯定的。我们需要获取setInterval()返回的定时器对象,通常将其命名为timer:

var i = 5;
var timer = setInterval(function(){
    i --;
    if(i < 0){
    clearInterval(timer);
}
    alert('i');
    
}, 1000);

在上述代码中,我们将setInterval的返回值赋给变量timer,并在外部定义变量i。每次执行interval内的回调函数时,我们将i减1。当i小于0时,调用清除定时器的逻辑:

clearInterval(timer对象);

这行代码用于清除定时器,只需传入setInterval()返回的对象即可停止周期性执行。

IV. 新年倒计时案例

最后,我们将结合所学的setTimeout()和setInterval()函数,联动实现一个新年倒计时案例:

期望实现的效果如下:

首先,在屏幕上实时展示60秒倒计时;

当倒计时归零后,弹出提示框展示“新年快乐!”;

有人看到需求后,可能会写出如下代码:

var element = document.getElementById("xin-nian")
var clock = 60;
var timer = null;
timer = setInterval(function () {
    element.innerHTML = "新年倒计时:" + clock + " !";
    console.log(clock)
    clock--;
    if (clock < 0) {
        clearInterval(timer);
        alert("新年快乐!");
    }
}, 1000);

乍看之下,这段代码似乎没有问题。但在实际运行中,由于向HTML写入内容存在微小的渲染延迟,可能导致在clock变为-1时,DOM尚未更新显示“0”,紧接着就触发了alert弹窗。因此,我们需要在倒计时最后一秒,利用setTimeout()增加一个缓冲延迟:

if (clock < 0) {
    clearInterval(timer);
    setTimeout(function () {
        alert("新年快乐!")
    }, 500)
}

于是,完整的代码逻辑应调整为:

<!DOCTYPE html>
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新年倒计时</title>
    <style>
        body {
            background-image: url(./1.jpg);
        }
    </style>
</head>
 
<body>
    <h1 id="xin-nian" style="text-align: center;margin-top: 250px;font-size: 50px;"></h1>
    <script>
        var element = document.getElementById("xin-nian")
        var clock = 60;
        var timer = null;
        timer = setInterval(function () {
            element.innerHTML = "新年倒计时:" + clock + " !";
            console.log(clock)
            clock--;
            if (clock < 0) {
                clearInterval(timer);
                setTimeout(function () {
                    alert("新年快乐!")
                }, 500)
            }
        }, 1000);
    </script>
 
</body>
 
</html>

最终实现的效果如以下动图所示:

I. 总述

总结

到此这篇关于JavaScript setTimeout和setInterval的用法与区别的文章就介绍到这了,更多相关js setTimeout和setInterval的用法内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

作者最新文章