防抖和節(jié)流

underscorejs庫:https://www.underscorejs.cn/debounce

  • _.debounce(function, wait, [immediate])
    返回 function 函數(shù)的防反跳版本, 將延遲函數(shù)的執(zhí)行(真正的執(zhí)行)在函數(shù)最后一次調(diào)用時(shí)刻的 wait 毫秒之后. 對(duì)于必須在一些輸入(多是一些用戶操作)停止到達(dá)之后執(zhí)行的行為有幫助。 例如: 渲染一個(gè) Markdown 格式的評(píng)論預(yù)覽, 當(dāng)窗口停止改變大小之后重新計(jì)算布局, 等等.
    在 wait 間隔結(jié)束時(shí),將使用最近傳遞給 debounced(去抖動(dòng))函數(shù)的參數(shù)調(diào)用該函數(shù)。
    傳參 immediate 為 true, debounce 會(huì)在 wait 時(shí)間間隔的開始調(diào)用這個(gè)函數(shù) 。(注:并且在 waite 的時(shí)間之內(nèi),不會(huì)再次調(diào)用。)在類似不小心點(diǎn)了提交按鈕兩下而提交了兩次的情況下很有用。
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

如果需要取消預(yù)定的 debounce ,可以在 debounce 函數(shù)上調(diào)用 .cancel()。

  • _.throttle(function, wait, [options])
    創(chuàng)建并返回一個(gè)像節(jié)流閥一樣的函數(shù),當(dāng)重復(fù)調(diào)用函數(shù)的時(shí)候,至少每隔 **wait **毫秒調(diào)用一次該函數(shù)。對(duì)于想控制一些觸發(fā)頻率較高的事件有幫助。

默認(rèn)情況下,throttle 將在你調(diào)用的第一時(shí)間盡快執(zhí)行這個(gè) function,并且,如果你在** wait **周期內(nèi)調(diào)用任意次數(shù)的函數(shù),都將盡快的被覆蓋。如果你想禁用第一次首先執(zhí)行的話,傳遞{leading: false},還有如果你想禁用最后一次執(zhí)行的話,傳遞{trailing: false}。

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

如果需要取消預(yù)定的 throttle ,可以在 throttle 函數(shù)上調(diào)用 .cancel()。

function restArguments(func, startIndex) {
  startIndex = startIndex == null ? func.length - 1 : +startIndex;
  return function() {
    var length = Math.max(arguments.length - startIndex, 0),
        rest = Array(length),
        index = 0;
    for (; index < length; index++) {
      rest[index] = arguments[index + startIndex];
    }
    switch (startIndex) {
      case 0: return func.call(this, rest);
      case 1: return func.call(this, arguments[0], rest);
      case 2: return func.call(this, arguments[0], arguments[1], rest);
    }
    var args = Array(startIndex + 1);
    for (index = 0; index < startIndex; index++) {
      args[index] = arguments[index];
    }
    args[startIndex] = rest;
    return func.apply(this, args);
  };
}

var now = Date.now || function() {
  return new Date().getTime();
};

export function debounce(func, wait, immediate) {
  var timeout, previous, args, result, context;

  var later = function() {
    var passed = now() - previous;
    if (wait > passed) {
      timeout = setTimeout(later, wait - passed);
    } else {
      timeout = null;
      if (!immediate) result = func.apply(context, args);
      // This check is needed because `func` can recursively invoke `debounced`.
      if (!timeout) args = context = null;
    }
  };

  var debounced = restArguments(function(_args) {
    context = this;
    args = _args;
    previous = now();
    if (!timeout) {
      timeout = setTimeout(later, wait);
      if (immediate) result = func.apply(context, args);
    }
    return result;
  });

  debounced.cancel = function() {
    clearTimeout(timeout);
    timeout = args = context = null;
  };

  return debounced;
}

export function throttle(func, wait, options) {
  var timeout, context, args, result;
  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;
  };

  var throttled = 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;
  };

  throttled.cancel = function() {
    clearTimeout(timeout);
    previous = 0;
    timeout = context = args = null;
  };

  return throttled;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 防抖(debounce):在指定的時(shí)間 n 秒后執(zhí)行回調(diào),如果在計(jì)算時(shí)間的過程中又被觸發(fā),則從新開始計(jì)算時(shí)間 fu...
    sharon_007閱讀 840評(píng)論 0 0
  • 什么是防抖 函數(shù)防抖(debounce) 是指在一定時(shí)間內(nèi),在動(dòng)作被連續(xù)頻繁觸發(fā)的情況下,動(dòng)作只會(huì)被執(zhí)行一次,也就...
    夕陽再美也會(huì)落幕閱讀 285評(píng)論 0 1
  • https://hzu-zuoxiong.gitbooks.io/frontend_note/javascript...
    Time_Notes閱讀 110評(píng)論 0 0
  • 一、認(rèn)識(shí)防抖和節(jié)流函數(shù) 防抖和節(jié)流的概念其實(shí)最早并不是出現(xiàn)在軟件工程中,防抖是出現(xiàn)在電子元件中,節(jié)流出現(xiàn)在流體流動(dòng)...
    咸魚不咸_123閱讀 1,067評(píng)論 0 1
  • 原文鏈接[https://github.com/tofrankie/blog/issues/248] 一、前言 相...
    越前君閱讀 1,080評(píng)論 0 15

友情鏈接更多精彩內(nèi)容