函數節流(throttle),指的是某個函數在必定時間間隔內(例如 3 秒)只執行一次,在這 3 秒內產生函數調用請求直接無視,也不會延長時間間隔。3 秒間隔結束後第一次遇到新的函數調用會觸發執行,而後在這新的 3 秒內依舊無視新的函數調用請求,以此類推。react
快速記憶:安安靜靜地作好這一件事,無論你怎麼打擾。瀏覽器
被頻繁調用的場景。若是有大量計算,頻繁操做 DOM,資源加載等行爲,可能會致使 UI 卡頓(線程阻塞),嚴重會致使瀏覽器奔潰。app
resize
、scroll
等事件;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));
複製代碼
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));
}
}
複製代碼