阅读 331

Javascript 函数节流

解读

函数节流(throttle),指的是某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内产生函数调用请求直接无视,也不会延长时间间隔。3 秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的 3 秒内依旧无视新的函数调用请求,以此类推。

快速记忆:安安静静地做好这一件事,不管你怎么打扰。

场景

被频繁调用的场景。如果有大量计算,频繁操作 DOM,资源加载等行为,可能会导致 UI 卡顿(线程阻塞),严重会导致浏览器奔溃。

  • 监听 Window 对象的 resizescroll 等事件;
  • 拖拽监听 mousemove 事件;
  • 文字输入时,对字符串处理或实时搜索;
  • ...

自我实现

  • 定时器。
  • 时间戳。记录上次执行的时间戳,然后每次触发事件执行回调,回调中判断当前时间戳距离上次时间戳的间隔是否达到时间差,如果达到则执行,并更新上次执行的时间戳,如此循环。
// 0.1.1/throttle.js
/**
 * 
 * @param {Function} callback 回调函数
 * @param {Number} wait       间隔时间
 * 
 * @return {Function} 节流函数
 */
function throttle(callback, wait = 3000) {
    let timer = null;
    let startTime;
    return function () {
        const ctx = this;
        const args = arguments;
        const now = +new Date();
        if (startTime && now < startTime + wait) {
            clearTimeout(timer);
            timer = setTimeout(function () {
                startTime = now;
                callback.apply(ctx, args);
            }, wait);
        } else {
            startTime = now;
            callback.apply(ctx, args);
        }
    }
}
复制代码

网页使用

// 0.1.1/throttle.page.js
const body = document.querySelector('body');
const btn = document.createElement('div');
btn.style = 'cursor: pointer; padding: 10px; background:red; border-radius: 5px; text-align: center; color:#fff;';
btn.innerHTML = '函数节流默认 3 秒';
body.append(btn);

function callback() {
    console.log('pr');
}
btn.addEventListener('click', throttle(callback));
复制代码

React.js

import React from 'react';
import { throttle } from './throttle';

// 使用
export default class ThrottleInReact extends React.Component {
    constructor() {
        super();
        this.change = throttle(e => {
            console.log(e.target.value);
        }, 1000);
    }

    onWindowResize = () => {
        console.log('resize');
    }

    onRemoveWindowResize = () => {
        console.log('remove resize');
    }

    handleChange = e => {
        e.persist();
        this.change(e);
    }

    render() {
        return (
            <input onChange={this.handleChange} />
        )
    }

    componentDidMount() {
        window.addEventListener('resize', throttle(this.onWindowResize, 60));
    }

    componentWillUnmount() {
       window.removeEventListener('resize', throttle(this.onRemoveWindowResize, 60));
    }
}
复制代码

你可以

上一篇:JavaScript 执行上下文和执行栈

下一篇:Javascript 函数防抖

关注下面的标签,发现更多相似文章
评论