2025年3月23日 星期日 甲辰(龙)年 月廿二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

JS函数节流和分时函数

时间:03-07来源:作者:点击数:83

函数节流和分时函数是 JS 高阶函数的两种具体应用场景,它们都是将函数作为返回值 return 到函数外部。

JS函数节流

函数节流就是降低函数被调用的频率,主要是针对 DOM 事件暴露出的问题提出的一种解决方案。例如,使用 resize、mousemove、mouseover、mouseout、keydown、keyup 等事件,都会频繁的触发事件。如果这些事件的处理函数中包含大量耗时操作,如 Ajax 请求、数据库查询、DOM 遍历等,则可能会让浏览器崩溃,严重影响用户体验。

例如,在大型网点平台的导航栏中,为了减轻 mouseover 和 mouseout 移动过快给浏览器处理带来的负担,特别是减轻涉及 Ajax 调用给服务器造成的极大负担,都会进行函数节流处理。

【设计思想】

让代码在间断的情况下重复执行。

【实现方法】

使用定时器对函数进行节流。

  • //函数节流封装代码,参数method表示要执行的函数,delay表示要延迟的时间,单位为毫秒
  • function throttle(mothod, delay) {
  • var timer = null; //定时器句柄
  • return function () { //返回节流函数
  • var context = this, args = arguments; //上下文函数和参数对象
  • clearTimeout(timer); //先清理未执行的函数
  • timer = setTimeout(function () { //重新定义定时器,记录新的定时器句柄
  • method.apply(context, args); //执行预设的函数
  • }, delay);
  • }
  • }

【应用代码】

设计文本框的 keyup 事件和窗口的 resize 事件,在浏览器中拖动窗口,或者在文本框中输入字符,然后在控制台查看事件响应次数和速度。

  • <input id="search" type="text" name="search">
  • <script>
  • function queryData(text) { console.log("搜索:" + text); }
  • var input = document.getElementById("search");
  • input.addEventListener("keyup", function(event) {queryData(this.value); });
  • var n = 0; //记录响应次数
  • function f() { console.log("响应次数:" + ++n); }
  • window.onresize = f;
  • </script>

通过观察可以发现,在拖动改变窗口的一瞬间,resize 事件响应了几十次。如果在文本框中输入字符,keyup 事件会立即响应,等不到用户输入完一个单词。

下面使用 throttle() 封装函数,把上面的事件处理函数转换为节流函数,同时设置延迟时间为 500 毫秒。

  • input.addEventListener("keyup", function(event) {
  • throttle(queryData, 500) (this.value);
  • });
  • window.onresize = throttle(f, 500);

重新进行测试,会发现拖动一次窗口改变大小,仅响应一次,而在文本框中输入字符时,也不会立即响应,等了半秒钟,才显示输入的字符。

JS分时函数

分时函数与函数节流的设计思路相近,但应用场景略有不同。当批量操作影响到页面性能时,如一次往页面中添加大量 DOM 节点,显然会给浏览器渲染带来影响,极端情况下可能会出现卡顿或假死等现象。

【设计思路】

 把批量操作分批处理,如把 1 秒钟创建 100 个节点,改为每隔 200 毫秒创建 100 个节点等。

【实现代码】

  • var timeChunk = function (ary, fn, count) {
  • var t;
  • var start = function () {
  • for (var i = 0; i < Math.min(count || 1, ary.length); i ++) {
  • var obj = ary.shift();
  • fn(obj);
  • }
  • }
  • return function () {
  • t = setInterval (function () {
  • if (ary.length === 0) { //如果全部节点都已经被创建好
  • return clearInterval(t);
  • }
  • start();
  • }, 200); //分批执行的时间间隔,也可以用参数的形式传入
  • };
  • };

timeChunk 函数接收 3 个参数,第 1 个参数表示批量操作时需要用到的数据,第 2 个参数封装了批量操作的逻辑函数,第 3 个参数表示分批操作的数量。

下面在页面中插入 10000 个 span 元素,由于数量巨大,这里使用分时函数进行分批操作。

  • var arr = [];
  • for (var i = 1; i < 10000; i ++) {
  • var span = document.creatElement("span");
  • span.style.padding = "6px 12px";
  • span.innerHTML = i;
  • arr.push(span);
  • }
  • var fn = function (obj) {
  • document.body.appendChild(obj);
  • }
  • timeChunk(arr, fn, 100) ();
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门