JavaScript面试题7:防抖和节流

简介: ●搜索框搜索输入。只需用户最后一次输入完,再发送请求●手机号、邮箱验证输入检测●窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

文章目录

什么是防抖和节流,以及如何编码实现?

定义

代码实现

区别

应用场景

什么是防抖和节流,以及如何编码实现?

本质上是优化高频率执行代码的一种手段

如:浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能

为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(节流)和debounce(防抖)的方式来减少调用频率


定义

节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时


代码实现

完成节流可以使用时间戳与定时器的写法


使用时间戳写法,事件会立即执行,停止触发后没有办法再次执行


function throttled1(fn, delay = 500) {

   let oldtime = Date.now()

   return function (...args) {

       let newtime = Date.now()

       if (newtime - oldtime >= delay) {

           fn.apply(null, args)

           oldtime = Date.now()

       }

   }

}

1

2

3

4

5

6

7

8

9

10

使用定时器写法,delay毫秒后第一次执行,第二次事件停止触发后依然会再一次执行


function throttled2(fn, delay = 500) {

   let timer = null

   return function (...args) {

       if (!timer) {

           timer = setTimeout(() => {

               fn.apply(this, args)

               timer = null

           }, delay);

       }

   }

}

1

2

3

4

5

6

7

8

9

10

11

可以将时间戳写法的特性与定时器写法的特性相结合,实现一个更加精确的节流。实现如下


function throttled(fn, delay) {

   let timer = null

   let starttime = Date.now()

   return function () {

       let curTime = Date.now() // 当前时间

       let remaining = delay - (curTime - starttime)  // 从上一次到现在,还剩下多少多余时间

       let context = this

       let args = arguments

       clearTimeout(timer)

       if (remaining <= 0) {

           fn.apply(context, args)

           starttime = Date.now()

       } else {

           timer = setTimeout(fn, remaining);

       }

   }

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

防抖


function debounce(func, wait) {

   let timeout;


   return function () {

       let context = this; // 保存this指向

       let args = arguments; // 拿到event对象


       clearTimeout(timeout)

       timeout = setTimeout(function(){

           func.apply(context, args)

       }, wait);

   }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

防抖如果需要立即执行,可加入第三个参数用于判断,实现如下:


function debounce(func, wait, immediate) {


   let timeout;


   return function () {

       let context = this;

       let args = arguments;


       if (timeout) clearTimeout(timeout); // timeout 不为null

       if (immediate) {

           let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发

           timeout = setTimeout(function () {

               timeout = null;

           }, wait)

           if (callNow) {

               func.apply(context, args)

           }

       }

       else {

           timeout = setTimeout(function () {

               func.apply(context, args)

           }, wait);

       }

   }

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

区别

相同点:


●都可以通过使用 setTimeout 实现

●目的都是,降低回调执行频率。节省计算资源


不同点:


●函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout 和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能

●函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次


例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次


应用场景

防抖在连续的事件,只需触发一次回调的场景有:


●搜索框搜索输入。只需用户最后一次输入完,再发送请求

●手机号、邮箱验证输入检测

●窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。


节流在间隔一段时间执行一次回调的场景有:


●滚动加载,加载更多或滚到底部监听

●搜索框,搜索联想功能



目录
相关文章
|
1月前
|
JavaScript 前端开发
常见的JS面试题
【8月更文挑战第5天】 常见的JS面试题
50 3
|
1天前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
1月前
|
JavaScript 前端开发 UED
JS 防抖与节流
防抖和节流是优化高频事件处理的技术。针对如`scroll`、`resize`等频繁触发的事件,它们能有效减少不必要的回调执行,节省资源。防抖确保在一段时间内仅执行最后一次操作,适用于输入框自动补全等场景;而节流则按固定间隔执行函数,适合拖拽、滚动事件。通过简单的JavaScript实现,可以显著提升应用性能和用户体验。
26 1
JS 防抖与节流
|
6天前
|
前端开发 JavaScript UED
JavaScript防抖和节流的使用及区别
JavaScript防抖和节流的使用及区别
7 0
|
1月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
21 0
|
1月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码
|
1月前
|
JavaScript 前端开发
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
|
30天前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
30天前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
30天前
|
Java
【Java基础面试三十七】、说一说Java的异常机制
这篇文章介绍了Java异常机制的三个主要方面:异常处理(使用try、catch、finally语句)、抛出异常(使用throw和throws关键字)、以及异常跟踪栈(异常传播和程序终止时的栈信息输出)。