函数防抖与撙节

underscore.js供应了许多很有效的函数,本日想说说个中的两个。这两个函数都用于限定函数的实行。

debounce

在诠释这个函数前,我们先从一个例子看下这个函数的运用场景。假定我们网站有个搜刮框,用户输入文本我们会自动遐想匹配出一些效果供用户挑选。我们能够起首想到的做法就是监听keypress事宜,然后异步去查询效果。这个要领自身是没错的,然则假如用户疾速的输入了一连串的字符,假定是10个字符,那末就会在霎时触发了10次的要求,这无疑不是我们想要的。我们想要的是用户住手输入的时刻才去触发查询的要求,这时刻函数防抖能够帮到我们。

函数防抖就是让某个函数在上一次实行后,满足守候某个时候内不再触发此函数后再实行,而在这个守候时候内再次触发此函数,守候时候会从新盘算。

我们先看下underscore.js里相干函数的定义:

_.debounce(function, wait, [immediate])

javascript// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
  var timeout, args, context, timestamp, result;

  var later = function() {
    var last = _.now() - timestamp;

    if (last < wait && last >= 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

  return function() {
    context = this;
    args = arguments;
    timestamp = _.now();
    var callNow = immediate && !timeout;
    if (!timeout) timeout = setTimeout(later, wait);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
};

参数function是须要举行函数防抖的函数;参数wait则是须要守候的时候,单元为毫秒;immediate参数假如为true,则debounce函数会在挪用时马上实行一次function,而不须要比及wait这个时候后,比方防备点击提交按钮时的屡次点击就能够运用这个参数。

所以,上面谁人场景,我们能够这么处置惩罚:

javascriptfunction query() { 
  //举行异步挪用查询 
}

var lazyQuery = _.debounce(query, 300);
$('#search').keypress(lazyQuery);

throttle

我们网站常常会有如许的需求,就是转动浏览器转动条的时刻,更新页面上的某些规划内容或许去挪用背景的某接口查询内容。一样的,假如不对函数挪用的频次加以限定的话,那末能够我们转动一次转动条就会发生N次的挪用了。然则此次的状况跟上面的有所不同,我们不是要在每完成守候某个时候后去实行某函数,而是要每距离某个时候去实行某函数,防止函数的过量实行,这个体式格局就叫函数撙节

一样的,我们看下underscore.js里相干函数的定义:

_.throttle(function, wait, [options])

javascript// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
_.throttle = function(func, wait, options) {
  var context, args, result;
  var timeout = null;
  var previous = 0;
  if (!options) options = {};
  var later = function() {
    previous = options.leading === false ? 0 : _.now();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };
  return function() {
    var now = _.now();
    if (!previous && options.leading === false) previous = now;
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
};

参数function是须要举行函数撙节的函数;参数wait则是函数实行的时候距离,单元是毫秒。option有两个选项,throttle第一次挪用时默许会马上实行一次function,假如传入{leading: false},则第一次挪用时不实行function。{trailing: false}参数则示意制止末了那一次耽误的挪用。详细能够看源码举行明白。

所以,在转动转动条的场景,我们能够这么做:

javascriptfunction handleScroll() { 
  //举行转动时的相干处置惩罚 
}

var throttled = _.throttle(handleScroll, 100);
$(window).scroll(throttled);

参考

http://underscorejs.org/#debounce
http://underscorejs.org/#throttle

    原文作者:icyfire
    原文地址: https://segmentfault.com/a/1190000002764479
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞