Dreamer Dreamer
首页
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

lycpan233

白日梦想家
首页
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • Vue

  • JavaScript

    • JavaScript部分特殊值判断记录
    • JavaScript各遍历方法对比
    • 防抖函数 Debounce
      • 什么是防抖函数
      • 实现方式
      • 思考
    • JavaScript 手撕深拷贝
    • JavaScript位运算应用场景
    • 浅谈Cookie和Session的区别
    • js 快速创建二维数组并初始化
    • js 获取变量准确类型
  • 前端
  • JavaScript
lycpan233
2024-01-04
目录

防抖函数 Debounce

# 什么是防抖函数

debounce 防抖函数,常用于某方法短时间内多次调用,但却不需要多次响应的场景。例如搜索的时候需要调用后端接口展示数据,但是在输入阶段是逐字录入的,这时候会触发多次接口,实际上仅需要输入完后触发一次即可。或者按钮短时间内多次点击,仅需要响应一次的场景。

# 实现方式

防抖函数的实现思想并不复杂,下面提供了一个简单示例:

function debounce(func, wait) {
  let timer;
  return function() {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(func, wait);
  };
};

const debounced = debounce(()=> console.log(123), 1000);
debounced()
1
2
3
4
5
6
7
8
9
10
11
12

# 思考

防抖函数在前端开发中经常使用,比如给事件绑定防抖函数或者绑定 DOM 事件。

<button @click="debounced"> 点击 </button>
1

所以我想,在服务端能不能用最小 demo,复现该效果。因此有了第一版 demo。

V1:

'use strict';
const http = require('http');

const host = '127.0.0.1';
const port = 7001;

const server = http.createServer((req, res) => {
  console.log('request received');

  function debounce(func, wait) {
    let timer;
    return function() {
      console.log('timer', !!timer);
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(func, wait);
    };
  }

  const debounced = debounce(() => console.log(123), 1000);

  debounced();

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});


server.listen(port, host, () => {
  console.log('Server running as ', host, ':', port);
});

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
26
27
28
29
30
31
32
33
34

当前版本在运行后不符合预期,多次请求,并不能共享 timer。后来更改了一版。

V2:

'use strict';
const http = require('http');

const host = '127.0.0.1';
const port = 7001;
let timer;

const server = http.createServer((req, res) => {
  console.log('request received');

  function debounce(func, wait) {
    return function() {
      console.log('timer', !!timer);
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(func, wait);
    };
  }

  const debounced = debounce(() => console.log(123), 1000);

  debounced();

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});


server.listen(port, host, () => {
  console.log('Server running as ', host, ':', port);
});
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
26
27
28
29
30
31
32
33

timer 提成全局变量以后,确实达到了预期,但是明显与在前端中的实践略有不同。研究一番以后有了第三版。

V3:

'use strict';
const http = require('http');

const host = '127.0.0.1';
const port = 7001;

function debounce(func, wait) {
  let timer;
  return function() {
    console.log('timer', !!timer);
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(func, wait);
  };
}

const debounced = debounce(() => console.log(123), 1000);

const server = http.createServer((req, res) => {
  console.log('request received');

  debounced();

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});


server.listen(port, host, () => {
  console.log('Server running as ', host, ':', port);
});
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
26
27
28
29
30
31
32
33

第三版也符合预期,但是感觉还差点意思,毕竟类似于将 func 抽到了全局。并不像前端,可以在逻辑里,封一个 debounced func 供组件和 DOM 用。

比较好奇的地方是,每次点击事件的触发和每次请求,有什么差异。为什么在请求事件中封装 func,可以共享参数。而每次请求会生成新的 func?

编辑 (opens new window)
上次更新: 2025/04/15, 03:48:14
JavaScript各遍历方法对比
JavaScript 手撕深拷贝

← JavaScript各遍历方法对比 JavaScript 手撕深拷贝→

最近更新
01
docker基础概念
02-26
02
js 获取变量准确类型
02-19
03
Mysql SQL 优化思路
02-18
更多文章>
Theme by Vdoing | Copyright © 2023-2025 Dreamer | MIT License
粤ICP备2025379918号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式