节流与防抖函数

Posted by Yinode on Friday, November 24, 2017

TOC

记录一下最近接触到的算法

节流与防抖

这两个函数都用于限制函数的执行。

debounce

函数防抖就是让某个函数在上一次执行后,满足等待某个时间内不再触发此函数后再执行,而在这个等待时间内再次触发此函数,等待时间会重新计算。如果带入到 DOM 操作中,其实就是防止一个输入框在多次触发事件的时候疯狂提交 AJAX 请求,而是当用户停止任何操作 xx 秒之后,这个请求才会被发起。

_在规定时间内的任何一次重新输入都会导致重新计算等待时间_。在基于事件模型的系统之中,这是非常常用的功能。

他接受三个参数,目标函数,等待时间,是否立即调用,第三个参数通常用于按钮触发请求的情况,通常我们需要这个按钮第一次被按下就触发请求,而在之后 的 xx 秒内,并不希望多次请求的发出。

比如搜索框就有非常常见的防抖需求,我们只希望用户在停下操作的时候进行查询,而不是瞬间触发非常多的请求。

function debounce(fn, delay) {
  let timer;
  return function(...args) {
    let ctx = this;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      return fn.apply(ctx, args);
    }, delay);
  };
}

throttle

节流函数的目的和防抖函数其实比较相似,都是限制函数的运行频率,而节流函数限制的方法是每当间隔 xx 秒内,就发放出一次能够运行函数的权限。

function throttle(fn, interval) {
  let last = 0;
  return function(...args) {
    let now = Date.now();
    let context = this;
    if (now - last > interval) {
      last = now;
      return fn.apply(context, ...args);
    }
  };
}

节流与防抖的区别

从本质上来讲,两者的作用都是为了节约资源。

  • 函数节流: 指定时间间隔内只会执行一次任务;
  • 函数防抖: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行

jsonp 转 json

其实就是一个简单的正则匹配,有时候当需要你进行转换的时候,又不方便创建一个函数来进行接收的时候,就可以利用这个正则来进行转换

var ret = response.data;
if (typeof ret === 'string') {
  var reg = /^\w+\(({[^]+})\)$/;
  var mathes = ret.match(reg);
  if (mathes) {
    ret = JSON.parse(mathes[1]);
  }
}

数组 shuffle 算法

应该算是非常经典的随机算法了,至于他是如何保证在一个盒子内进行随机互换能达到所有的概率都平均分布我就不知道了,这可能需要数学上的严谨的证明。

export function shuffle(arr) {
  let _arr = arr.slice();
  for (let i = 0; i < _arr.length; i++) {
    let j = getRandomInt(0, i);
    let t = _arr[i];
    _arr[i] = _arr[j];
    _arr[j] = t;
  }
  return _arr;
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

他的迭代过程类似这样,每次取出一个值并和一个空间内的随机值进行互换,每次取出的值下标是叠加递增(x+1)的,而空间则在不断的变大。

对象深度克隆

function deepClone(o1, o2) {
  for (key in o1) {
    if (typeof o1[key] === 'object') {
      o2[key] = {};
      deepClone(o1[key], o2[key]);
    } else {
      o2[key] = o1[key];
    }
  }
}