函数防抖(debounce)的应用场景

  1. 连续的事件,只需触发一次的回调场景有:
  2. 搜索框搜索输入。
  3. 只需要用户最后一次输入完再发送请求 手机号、邮箱格式的输入验证检测
  4. 窗口大小的resize 。只需窗口调整完成后,计算窗口的大小,防止重复渲染

函数节流(throttle)的应用场景

  1. 间隔一段时间执行一次回调的场景有:
  2. 滚动加载,加载更多或滚动到底部监听
  3. 谷歌搜索框,搜索联想功能
  4. 高频点击提交,表单重复提交
  5. 省市信息对应字母快速选择

1.防抖

  1. export const boDebounce = (func, wait, immediate) => {
  2. console.log("进入防抖");
  3. let timeout;
  4. return function () {
  5. const context = this;
  6. const args = [...arguments];
  7. if (timeout) clearTimeout(timeout);
  8. if (immediate) {
  9. const callNow = !timeout;
  10. timeout = setTimeout(() => {
  11. timeout = null;
  12. }, wait)
  13. if (callNow) func.apply(context, args)
  14. }
  15. else {
  16. timeout = setTimeout(() => {
  17. func.apply(context, args)
  18. }, wait);
  19. }
  20. }
  21. }
  22. 使用:
  23. <template>
  24. <div>
  25. <el-input v-model="input" @input="getSearch"> </el-input>
  26. <el-input v-model="nowInput" @input="getNowSearch"> </el-input>
  27. </div>
  28. </template>
  29. <script>
  30. import { debounce, nowDebounce } from "@/store/debounce.js";
  31. export default {
  32. data() {
  33. return {
  34. input: "",
  35. nowInput: "",
  36. };
  37. },
  38. methods: {
  39. getSearch: boDebounce(
  40. function () {
  41. console.log("拿到数据");
  42. },
  43. 1000,
  44. false
  45. ),
  46. getSearch: debounce(function () {
  47. console.log("拿到数据");
  48. }, 1000),
  49. getNowSearch: nowDebounce(function () {
  50. console.log("立即拿到数据");
  51. }, 1000),
  52. },
  53. };
  54. </script>

2.节流

  1. export const boThrottle = (func, wait, type) => {
  2. console.log("进入节流")
  3. let previous;
  4. let timeout
  5. if (type === "now") {
  6. previous = 0;
  7. } else if (type === "late") {
  8. timeout;
  9. }
  10. return function () {
  11. let context = this;
  12. let args = arguments;
  13. if (type === "now") {
  14. let now = Date.now();
  15. if (now - previous > wait) {
  16. func.apply(context, args);
  17. previous = now;
  18. }
  19. } else if (type === "late") {
  20. if (!timeout) {
  21. timeout = setTimeout(() => {
  22. timeout = null;
  23. func.apply(context, args)
  24. }, wait)
  25. }
  26. }
  27. }
  28. }
  29. 使用:
  30. <template>
  31. <div>
  32. <div class="mouseDiv" @mousemove="mouseNoMoveEvent">{{ mouseNowNum }}</div>
  33. <div class="mouseDiv" @mousemove="mouseMoveEvent">{{ mouseNum }}</div>
  34. </div>
  35. </template>
  36. <script>
  37. import {
  38. throttle,
  39. nowThrottle,
  40. boThrottle
  41. } from "@/store/debounce.js";
  42. export default {
  43. data() {
  44. return {
  45. mouseNowNum: 0,
  46. mouseNum: 0,
  47. };
  48. },
  49. methods: {
  50. mouseNoMoveEvent: nowThrottle(function () {
  51. this.mouseNowNum++;
  52. console.log("立即执行");
  53. }, 1000),
  54. mouseMoveEvent: throttle(function () {
  55. this.mouseNum++;
  56. console.log("延迟执行");
  57. }, 1000),
  58. mouseNoMoveEvent: boThrottle(
  59. function () {
  60. this.mouseNowNum++;
  61. console.log("立即执行");
  62. },
  63. 1000,
  64. "now"
  65. ),
  66. mouseMoveEvent: boThrottle(
  67. function () {
  68. this.mouseNum++;
  69. console.log("延迟执行");
  70. },
  71. 1000,
  72. "late"
  73. ),
  74. },
  75. };
  76. </script>
  77. <style>
  78. .mouseDiv {
  79. margin: 20px auto;
  80. width: 1000px;
  81. height: 400px;
  82. line-height: 400px;
  83. text-align: center;
  84. font-size: 30px;
  85. background-color: lightblue;
  86. }
  87. </style>

3.节流 时间戳版,立即执行版

  1. export const nowThrottle = (func, wait) => {
  2. console.log("进入节流")
  3. var previous = 0;
  4. return function () {
  5. let now = Date.now();
  6. let context = this;
  7. let args = arguments;
  8. if (now - previous > wait) {
  9. func.apply(context, args);
  10. previous = now;
  11. }
  12. }
  13. }

4.节流 计时器版,延迟执行版

  1. export const throttle = (func, wait) => {
  2. console.log("进入节流")
  3. let timeout;
  4. return function () {
  5. let context = this;
  6. let args = arguments;
  7. if (!timeout) {
  8. timeout = setTimeout(() => {
  9. timeout = null;
  10. func.apply(context, args)
  11. }, wait)
  12. }
  13. }
  14. }