java script 防抖和节流

本文介绍了JavaScript中防抖和节流技术的概念及其应用场景。通过实际案例,如页面滚动条监听和文本框输入请求,展示了如何封装这两种常用的技术。

文章目录

概念

         防抖:就是一定时间内,只会执行最后一次任务。

         节流:就是一定时间内,只执行一次。

防抖

         防抖函数的封装使用

节流

         节流函数的封装使用

防抖

<button id="debounce">点我防抖!</button>

$('#debounce').on('click', debounce());

function debounce() {
    let timer;
    // 闭包
    return function () {
        clearTimeout(timer);
        timer = setTimeout(() => {
            // 需要防抖的操作...
            console.log("防抖成功!");
        }, 500);
    }
}

函数防抖的应用场景,最常见的就是页面滚动条监听的例子,来进行解析:

let timer;
window.onscroll = function () {
    clearTimeout(timer);
    timer = setTimeout(function () {
        //滚动条位置
        let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        console.log('滚动条位置:' + scrollTop);
    }, 200)
}

防抖函数的封装使用

/**
 * 防抖函数
 * @param fn 事件触发的操作
 * @param delay 多少毫秒内连续触发事件,不会执行
 * @returns {Function}
 */
function debounce(fn,delay) {
    let timer = null;
    return function () {
        let self = this,
            args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            fn.apply(self,args);
        },delay);
    }
}

window.onscroll = debounce(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
},200)

节流

<button id="throttle">点我节流!</button>

$('#throttle').on('click', throttle());

function throttle(fn) {
    let flag = true;
    // 闭包
    return function () {
        if (!flag) {
            return;
        }
        flag = false;
        setTimeout(() => {
            console.log("节流成功!");
            flag = true;
        }, 1000);
    };
}

函数节流应用的实际场景,根据文本框中输入的内容自动请求后台数据

节流函数的封装使用

<input type="text" value="" id="input">

$('#input').on('keyup', throttle(function () {
    console.log($(this).val());
    // ajax后台请求....
}, 1000));

/**
 * 节流函数
 * @param fn 事件触发的操作
 * @param delay 间隔多少毫秒需要触发一次事件
 */
function throttle(fn, delay) {
    let flag = true;
    return function () {
        let self = this,
            args = arguments;
        if (!flag) {
            return;
        }
        flag = false;
        setTimeout(() => {
            fn.apply(self, args);
            flag = true;
        }, delay);
    }
}

<think>好的,用户想了解JavaScript中的计时函数及其使用方法,特别是setIntervalsetTimeout。首先,我需要确认用户的需求,他们可能是在开发网页时需要定时执行某些操作,比如轮询数据、动画效果或者延迟执行任务。根据提供的引用内容,用户已经给出了一些关于setTimeoutsetInterval的示例代码解释。我需要将这些信息整合起来,以清晰的结构呈现。首先,应该介绍这两个函数的基本用法,然后讨论它们的区别,接着是注意事项,比如清除定时器避免内存泄漏。用户提供的引用中提到了宏任务微任务的区别,这可能涉及到事件循环的知识,但用户的问题可能更基础,所以需要适当提及但不过于深入。另外,用户提到了防抖节流,这些是常见的高级应用技巧,应该包含在高级应用部分。需要注意的是,用户可能对如何正确使用这些函数以及常见的陷阱感兴趣,比如定时器不准的问题,或者忘记清除定时器导致的内存泄漏。同时,用户提供的示例代码中有使用HTML按钮控制定时器的例子,这可以作为实践示例来展示如何结合DOM操作使用计时函数。 需要确保回答结构清晰,分点说明,并包含代码示例。同时,按照用户的系统指令,数学公式要用正确的LaTeX格式,但在这个问题中可能涉及较少。最后生成相关问题,帮助用户深入理解。现在开始组织内容:先定义两个函数,基本语法,使用示例,区别对比,注意事项,高级技巧,最后实践案例。确保每个部分都有引用支持,并正确标注引用来源。检查是否有遗漏点,比如清除定时器的方法,以及事件循环的影响。</think>### JavaScript计时函数详解与使用指南 JavaScript 提供了两个核心计时函数 `setTimeout`` `setInterval``,它们通过事件循环机制实现异步定时操作[^1][^3]。以下是详细解析: --- #### **一、基础计时函数** 1. **`setTimeout`:单次延时执行** ```javascript // 语法:setTimeout(callback, delay, arg1, arg2...) const timerId = setTimeout(() => { console.log('延时1秒后执行'); }, 1000); // 清除定时器 clearTimeout(timerId); ``` - 延迟时间单位为毫秒(ms) - 支持传递参数给回调函数:`setTimeout((a,b) => {}, 1000, 1, 2)` 2. **`setInterval`:周期性重复执行** ```javascript // 语法:setInterval(callback, interval, arg1, arg2...) const intervalId = setInterval(() => { console.log('每隔2秒执行一次'); }, 2000); // 清除定时器 clearInterval(intervalId); ``` --- #### **二、核心区别对比** | 特性 | `setTimeout` | `setInterval` | |--------------------|----------------------------------|---------------------------------| | **执行次数** | 单次执行 | 无限循环直到清除 | | **误差累积** | 无累积误差(单次触发) | 可能因代码执行时间产生累积误差 | | **内存泄漏风险** | 较低 | 较高(需手动清除) | | **适用场景** | 延迟操作、单次动画 | 轮询、周期性更新 | --- #### **三、关键注意事项** 1. **事件循环机制** 计时器回调属于**宏任务(macrotask)**,会在当前执行栈清空后执行[^1]: ```javascript console.log('Start'); setTimeout(() => console.log('Timeout'), 0); Promise.resolve().then(() => console.log('Promise')); console.log('End'); // 输出顺序:Start → End → Promise → Timeout ``` 2. **定时器精度问题** JavaScript计时器最小间隔为$4ms$(浏览器规范限制),且受主线程阻塞影响: ```javascript let start = Date.now(); setTimeout(() => { console.log(`实际延迟: ${Date.now() - start}ms`); // 可能大于1000ms }, 1000); ``` 3. **内存管理** 未清除的定时器会导致内存泄漏,应在组件卸载时清除: ```javascript let intervalId; function startPolling() { intervalId = setInterval(fetchData, 5000); } function stopPolling() { clearInterval(intervalId); } ``` --- #### **四、高级应用技巧** 1. **用`setTimeout`模拟`setInterval`** 避免误差累积的更可控实现[^1]: ```javascript function customInterval(callback, interval) { let timer; function execute() { callback(); timer = setTimeout(execute, interval); // 递归调用 } timer = setTimeout(execute, interval); return { clear: () => clearTimeout(timer) }; } ``` 2. **防抖(debounce)与节流(throttle)** - **防抖**:连续触发时只执行最后一次 ```javascript function debounce(fn, delay) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); }; } ``` - **节流**:固定间隔内只执行一次 ```javascript function throttle(fn, interval) { let lastTime = 0; return (...args) => { const now = Date.now(); if (now - lastTime >= interval) { fn(...args); lastTime = now; } }; } ``` --- #### **五、实践案例** ```html <!DOCTYPE html> <html> <body> <button onclick="startCounter()">开始计数</button> <span id="count">0</span> <button onclick="stopCounter()">停止</button> <script> let counter = 0; let timerId; function startCounter() { timerId = setInterval(() => { counter++; document.getElementById('count').textContent = counter; }, 1000); } function stopCounter() { clearInterval(timerId); } </script> </body> </html> ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值