50  
前端的防抖与节流
作者: 方凯 于 2020年10月20日 发布在分类 / 计算机专业 / 前端相关 下,并于 2020年10月20日 编辑
防抖 节流

 防抖与节流

防抖和节流可以说是一对好基友,也是前端面试的手写热点考题。防抖和节流其实都是在规避频繁触发回调导致大量计算,从而影响页面发生抖动甚至卡顿。简单的说将多次回调比如页面点击或ajax调用变为一次。防抖和节流的区别在于以第一次为准还是最后一次为准。

需求

1. 节流Throttle - 调用多次、只第一次调用有效

在一段时间内,不论触发多少次调用,都以第一次为准。 输入框补全提示,只需要每两秒补全一次。

用测试用例表示

it("节流Throttle", (done) => {  const { throttle } = require("../index");   // 定义一个Mock函数  const mockFn = jest.fn();   // 封装为节流方法  const fn = throttle(mockFn, 10);   // 同步调用两次  fn(1);  fn(2);   setTimeout(() => {  const calls = mockFn.mock.calls;   // 断言 mock方法只调用一次  expect(calls.length).toBe(1);  // 根据参数判断以第一次调用为准  expect(calls[0][0]).toBe(1);  done();  }, 50); }); 复制代码

2. 防抖Debounce 最后一次为准

在一段时间内,不论触发多少期回调,都已最后一次为准。 比如:以用户拖拽改变窗口大小,触发 resize 事件为例,会触发组件重新布局,这里面只有最后一次调用是有意义的。

it("防抖Debounce", (done) => {  const { debounce } = require("../index");  const mockFn = jest.fn();  // 封装一个防抖函数  const fn = debounce(mockFn, 10);   // 连续两次调用  fn(1);  fn(2);   setTimeout(() => {  const calls = mockFn.mock.calls;  // 断言只调用一次  expect(calls.length).toBe(1);  // 断言以最后一次调用为准  expect(calls[0][0]).toBe(2);  done();  }, 50); }); 复制代码

功能实现

节流

主要思路利用时间戳判断,每次调用判断和上一次调用的时间差异确定是否需要调用。 throttle实际是一个工厂函数,可以将一个函数封装为一个带有节流功能的函数。

module.exports.throttle = (fn, delay) => {  // 定义上次触发时间  let last = 0;  return (...args) => {  const now = + Date.now();  console.log("call", now, last, delay);  if (now > last + delay) {  last = now;  fn.apply(this, args);  }  }; };  复制代码

防抖

实现的话可以使用定时器执行函数,新调用发生时如果旧调用没有执行就清除之前的定时器。

/**  * 防抖Debounce  */ module.exports.debounce = (fn, delay) => {  let timer;  return (...args) => {  // 判断定时器是否存在,清除定时器  if (timer) {  clearTimeout(timer);  }   // 重新调用setTimeout  timer = setTimeout(() => {  fn.apply(this, args);  }, delay);  }; }; 复制代码

测试





 推荐知识


 访问权限

创建人 方凯
文档编辑权限 创建者私有
文档阅读权限 来自分类
分类阅读权限 所有人
分类编辑权限 所有人
分类审核权限 无需审核
分类预览权限 所有人
分类下载权限 所有人
 历史版本

修改日期 修改人 备注
2020-10-20 09:47:37[当前版本] 方凯 格式调整
2020-10-20 09:47:13 方凯 CREAT

 附件

附件类型

IMAGEIMAGE

WCP知识管理系统-Vfree.4.2.0/419