MST
星途 面试题库

面试题:JavaScript防抖与节流在复杂场景下的综合应用

假设你正在开发一个复杂的Web应用,其中有一个搜索框实时搜索功能,同时页面中有一个窗口大小变化时触发的布局调整函数。要求综合运用防抖与节流技术,以确保性能最优,同时要处理好搜索结果显示与布局调整的时机问题。请描述实现思路并给出关键代码片段。
31.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 防抖技术
    • 对于搜索框实时搜索功能,使用防抖技术可以避免用户在快速输入时频繁触发搜索请求。当用户输入停止后,等待一定时间(例如300毫秒),再发起搜索请求,这样可以减少不必要的请求次数,提升性能。
  2. 节流技术
    • 对于窗口大小变化触发的布局调整函数,使用节流技术。因为窗口大小变化事件(如 resize)可能会被非常频繁地触发,如果每次都执行布局调整函数,会严重影响性能。通过节流,设置一个固定的时间间隔(例如200毫秒),在这个时间间隔内,无论窗口大小变化触发了多少次,只执行一次布局调整函数。
  3. 处理搜索结果显示与布局调整的时机
    • 搜索结果显示在防抖后的搜索请求返回数据后进行更新。
    • 布局调整在节流后的窗口大小变化事件处理函数中执行。

关键代码片段

使用JavaScript实现(假设使用原生JavaScript,不依赖框架)

  1. 防抖函数
function debounce(func, delay) {
    let timer;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}
  1. 节流函数
function throttle(func, interval) {
    let lastTime = 0;
    return function() {
        const context = this;
        const args = arguments;
        const now = new Date().getTime();
        if (now - lastTime >= interval) {
            func.apply(context, args);
            lastTime = now;
        }
    };
}
  1. 搜索框实时搜索(结合防抖)
<input type="text" id="searchInput" placeholder="搜索">
<script>
const searchInput = document.getElementById('searchInput');
const debouncedSearch = debounce(() => {
    const searchText = searchInput.value;
    // 这里发起搜索请求,例如使用fetch
    fetch(`/search?query=${searchText}`)
      .then(response => response.json())
      .then(data => {
            // 显示搜索结果,假设页面中有一个id为searchResults的元素用于显示结果
            const searchResults = document.getElementById('searchResults');
            searchResults.innerHTML = '';
            data.forEach(result => {
                const li = document.createElement('li');
                li.textContent = result;
                searchResults.appendChild(li);
            });
        });
}, 300);
searchInput.addEventListener('input', debouncedSearch);
</script>
  1. 窗口大小变化布局调整(结合节流)
<script>
const throttledResize = throttle(() => {
    // 这里进行布局调整逻辑,例如修改元素的CSS样式
    const mainContainer = document.getElementById('mainContainer');
    if (window.innerWidth < 600) {
        mainContainer.style.flexDirection ='column';
    } else {
        mainContainer.style.flexDirection = 'row';
    }
}, 200);
window.addEventListener('resize', throttledResize);
</script>

使用React实现

  1. 防抖函数(与上述相同)
function debounce(func, delay) {
    let timer;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}
  1. 节流函数(与上述相同)
function throttle(func, interval) {
    let lastTime = 0;
    return function() {
        const context = this;
        const args = arguments;
        const now = new Date().getTime();
        if (now - lastTime >= interval) {
            func.apply(context, args);
            lastTime = now;
        }
    };
}
  1. 搜索框实时搜索(结合防抖)
import React, { useState, useEffect } from'react';

function debounce(func, delay) {
    let timer;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

const SearchComponent = () => {
    const [searchText, setSearchText] = useState('');
    const [searchResults, setSearchResults] = useState([]);

    const fetchSearchResults = () => {
        fetch(`/search?query=${searchText}`)
          .then(response => response.json())
          .then(data => {
                setSearchResults(data);
            });
    };

    const debouncedFetch = debounce(fetchSearchResults, 300);

    const handleSearchChange = (e) => {
        setSearchText(e.target.value);
        debouncedFetch();
    };

    return (
        <div>
            <input type="text" value={searchText} onChange={handleSearchChange} placeholder="搜索" />
            <ul>
                {searchResults.map((result, index) => (
                    <li key={index}>{result}</li>
                ))}
            </ul>
        </div>
    );
};

export default SearchComponent;
  1. 窗口大小变化布局调整(结合节流)
import React, { useEffect } from'react';

function throttle(func, interval) {
    let lastTime = 0;
    return function() {
        const context = this;
        const args = arguments;
        const now = new Date().getTime();
        if (now - lastTime >= interval) {
            func.apply(context, args);
            lastTime = now;
        }
    };
}

const LayoutComponent = () => {
    const handleResize = () => {
        // 这里进行布局调整逻辑,例如修改组件状态控制样式
    };

    const throttledResize = throttle(handleResize, 200);

    useEffect(() => {
        window.addEventListener('resize', throttledResize);
        return () => {
            window.removeEventListener('resize', throttledResize);
        };
    }, []);

    return (
        <div>
            {/* 页面布局内容 */}
        </div>
    );
};

export default LayoutComponent;