防抖

防抖 (debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户输入,只需再输入完成后做一次输入校验即可。

  1. function debounce(fn, wait, immediate) {
  2. let timer = null;
  3. return function() {
  4. let args = arguments;
  5. let context = this;
  6. if (immediate) {
  7. fn.apply(context, args);
  8. }
  9. if (timer) clearTimeout(timer);
  10. timer = setTimeout(() => {
  11. fn.apply(context, args);
  12. }, wait)
  13. }
  14. }

节流

节流(throttle): 每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作,通常使用场景: 滚动条事件 或者 resize 事件,通常每隔 100~500 ms 执行一次即可。

简易实现:

  1. function throttle(fn, wait, immediate) {
  2. let timer = null;
  3. let callNow = immediate;
  4. return function() {
  5. const args = arguments;
  6. const context = this;
  7. if (callNow) {
  8. fn.apply(context, args);
  9. callNow = false;
  10. }
  11. if (!timer) {
  12. timer = setTimeout(() => {
  13. fn.apply(context, args);
  14. timer = null;
  15. }, wait);
  16. }
  17. }
  18. }

复杂实现:

  1. function throttle(fn, wait) {
  2. let context;
  3. let timer;
  4. let previous = 0;
  5. return function() {
  6. context = this;
  7. const args = arguments;
  8. const now = +new Date();
  9. const t = wait - (now - previous);
  10. if (t <= 0) {
  11. if (timer) {
  12. clearTimeout(timer);
  13. timer = null;
  14. }
  15. fn.apply(context, args);
  16. previous = now;
  17. } else if (!timer) {
  18. timer = setTimeout(() => {
  19. fn.apply(context, args);
  20. timer = null;
  21. previous = +new Date();
  22. }, t);
  23. }
  24. }
  25. }