节流模式(Throttler)
对重复的业务逻辑进行节流控制,执行最后一次操作并取消其他操作,以提高性能。
简单的节流器示例
// 节流器
const throttle = (function () {
let timer = null;
return function ({
handle = () => {
}, time = 300 }) {
// 清除计时器句柄
clearTimeout(timer);
// 创建计时器句柄,延迟函数的执行
timer = setTimeout(() => {
handle();
}, time);
};
}());
let n = 0;
window.onresize = function () {
throttle({
handle() {
console.log(n++);
},
time: 500
});
};
鼠标移入移出示例
鼠标移入/移出标题上时,显示/隐藏简介
<style>
#desc {
display: none;
background-color: #eee;
border: 1px solid #ccc;
padding: 10px 20px;
}
#content {
text-align: justify;
text-indent: 2em;
}
</style>
<h3 id="title">You瞧谁不起 - 道不尽世间的沧桑,诉不完人生的悲凉</h3>
<p id="desc">简介:人海茫茫,你我依旧孤独~~~</p>
<div id="content">
就我个人来说,中午吃什么对我的意义,不能不说非常重大。 叔本华说过一句富有哲理的话,普通人只想到如何度过时间,有才能的人设法利用时间。这句话语虽然很短,但令我浮想联翩。 贝多芬说过一句富有哲理的话,卓越的人一大优点是:在不利与艰难的遭遇里百折不饶。这似乎解答了我的疑惑。 我认为, 了解清楚中午吃什么到底是一种怎么样的存在,是解决一切问题的关键。 一般来讲,我们都必须务必慎重的考虑考虑。 吕凯特曾经说过,生命不可能有两次,但许多人连一次也不善于度过。这似乎解答了我的疑惑。 一般来说, 一般来讲,我们都必须务必慎重的考虑考虑。 中午吃什么因何而发生。
</div>
function $(id) {
return document.getElementById(id);
}
$('title').addEventListener('mouseenter', function (e) {
$('desc').style.display = 'block';
}, false);
$('title').addEventListener('mouseleave', function (e) {
$('desc').style.display = 'none';
}, false);
- 缺点:
- 当我们阅读下边内容时,鼠标不小心移入移除到标题区域时,简介区域会立即的显示隐藏,很影响我们后续的布局和阅读体验
节流模式
解决上述问题
function $(id) {
return document.getElementById(id);
}
// 节流器
const throttle = (function () {
let timer = null;
return function ({
handle = () => {
}, time = 300 }) {
// 清除计时器句柄
clearTimeout(timer);
// 创建计时器句柄,延迟函数的执行
timer = setTimeout(() => {
handle();
}, time);
};
}());
$('title').addEventListener('mouseenter', function (e) {
throttle({
handle() {
$('desc').style.display = 'block';
},
time: 500
});
}, false);
$('title').addEventListener('mouseleave', function (e) {
throttle({
handle() {
$('desc').style.display = 'none';
},
time: 500
});
}, false);
输入框输入请求接口示例
避免每次输入都立即去调用接口
function $(id) {
return document.getElementById(id);
}
// 节流器
const throttle = (function () {
let timer = null;
return function ({
handle = () => {
}, time = 300 }) {
// 清除计时器句柄
clearTimeout(timer);
// 创建计时器句柄,延迟函数的执行
timer = setTimeout(() => {
handle();
}, time);
};
}());
// 搜索接口
function search(q) {
console.log(q.value);
}
$('search').addEventListener('input', function (e) {
throttle({
handle() {
search(e.target);
},
time: 500
})
});
特点
痛点
:- 对于
DOM的操作
,常常会占用大量的内存资源
和cpu处理时间
。甚至大量的DOM操作
在一些浏览器中也很可能导致浏览器的崩溃
。由于JavaScript
的单线程处理机制
,导致DOM操作占用大量资源
时会严重堵塞后面重要程序的执行
。
- 对于
节流模式的核心思想
:- 核心思想是
创建计时器
,延迟程序的执行
。这也使得计时器中回调函数
的操作异步执行
- 这里的
异步执行
并不是
说JavaScript是多线程语言
,JavaScript
从设计之初就是单线程语言
,异步
只是说脱离原来程序执行的顺序
,看上去,异步程序
像是在同时执行
。但是某一时刻
,当前执行的程序
一定是所有异步程序(包括原程序)中的某一个
- 这里的
- 核心思想是
- 由此可看出节流模式主要有
两点优势
:程序能否执行是可控的
- 执行前的某一时刻是否清除计时器来决定程序是否可以继续执行;
程序是异步的
- 由于计时器机制,使得程序脱离原程序而异步执行(当然随着worker技术的兴起,也可开启多线程模式实现),因此不会影响后面的程序的正常执行。在其他方面,比如对异步请求(ajax)应用节流,此时可以优化请求次数来节省资源;