MST
星途 面试题库

面试题:JavaScript中setTimeout与setInterval的执行机制对比

请阐述JavaScript中setTimeout和setInterval在执行机制上的主要区别,并举例说明在什么场景下适合使用setTimeout,什么场景下适合使用setInterval。
27.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

执行机制区别

  1. setTimeout
    • setTimeout 用于在指定的延迟时间(单位为毫秒)之后执行一次指定的函数或代码块。
    • 它只执行一次,当延迟时间到达后,将回调函数放入任务队列中,等待主线程空闲时执行。
  2. setInterval
    • setInterval 会按照指定的时间间隔(单位为毫秒)重复执行指定的函数或代码块。
    • 它会周期性地将回调函数放入任务队列,不管前一次回调函数是否已经执行完成,只要间隔时间一到就会再次添加到任务队列,可能会导致回调函数执行的时间间隔不准确,特别是当回调函数执行时间较长时。

适用场景

  1. 适合 setTimeout 的场景
    • 延迟操作:例如,在页面加载完成3秒后显示一个提示框。
    window.onload = function() {
        setTimeout(() => {
            alert('页面已加载3秒');
        }, 3000);
    };
    
    • 异步任务调度:在某个异步操作完成后,延迟一段时间执行另一个操作。比如,在一个AJAX请求成功获取数据后,延迟2秒再更新页面。
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'data.json', true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            setTimeout(() => {
                const data = JSON.parse(xhr.responseText);
                // 更新页面操作
                document.getElementById('result').innerHTML = data.message;
            }, 2000);
        }
    };
    xhr.send();
    
  2. 适合 setInterval 的场景
    • 周期性更新:如实时时钟显示,每秒更新一次时间。
    setInterval(() => {
        const now = new Date();
        document.getElementById('clock').innerHTML = now.toLocaleTimeString();
    }, 1000);
    
    • 轮询数据:定时向服务器请求最新数据,比如每5秒请求一次服务器获取最新的消息列表。
    setInterval(() => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', 'latest - messages.json', true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                const messages = JSON.parse(xhr.responseText);
                // 更新消息列表操作
                const list = document.getElementById('message - list');
                list.innerHTML = '';
                messages.forEach(message => {
                    const li = document.createElement('li');
                    li.textContent = message;
                    list.appendChild(li);
                });
            }
        };
        xhr.send();
    }, 5000);