rogerxu / rogerxu.github.io

Roger Xu's Blog
2 stars 2 forks source link

Lodash #234

Open rogerxu opened 5 years ago

rogerxu commented 5 years ago

Debounce

https://lodash.com/docs/4.17.15#debounce

Debouncing and Throttling Explained Through Examples | CSS-Tricks

JavaScript专题之跟着underscore学防抖 · Issue #22 · mqyqingfeng/Blog

实例解析防抖动(Debouncing)和节流阀(Throttling) | Alon's Blog

Concept

防抖的原理就是:你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行。

总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行。

Trailing

"group" multiple sequential calls in a single one.

返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行

https://res.cloudinary.com/css-tricks/image/fetch/q_auto,f_auto/https://css-tricks.com/wp-content/uploads/2016/04/debounce.png image

Leading edge

Trigger the function execution immediately, but not fire again until there is a pause in the rapid calls.

https://res.cloudinary.com/css-tricks/image/fetch/q_auto,f_auto/https://css-tricks.com/wp-content/uploads/2016/04/debounce-leading.png image

Implementation

const debounce = (func, wait) => {
  let timer;

  return function(...args) {
    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
};

// 处理函数
function handle() {
  console.log(new Date());
}

// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));

Examples

Resize

Use the default trailing option for the resize event, because we are only interested on the final value, after user stops resizing the browser.

window.addEventListener('resize', _.debounce(() => displayInfo($right_panel), 400));

keypress on autocomplete form with Ajax request

Only send the request when the user stops typing. We want to wait to the last letter typed.

const inputBox = document.querySelector('.autocomplete');
inputBox.addEventListener('keydown', _.debounce(makeRequest, 1000));
rogerxu commented 5 years ago

Throttle

JavaScript专题之跟着 underscore 学节流 · Issue #26 · mqyqingfeng/Blog

JS的防抖与节流 - 前端麻辣烫

Throttle guarantees the execution of the function regularly, at least every X milliseconds.

防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

Implementation

Timestamp

function throttle(func, delay) {
  let prev = Date.now();

  return function(...args) {
    let context = this;
    let now = Date.now();

    if (now - prev >= delay) {
      func.apply(context, args);
      prev = Date.now();
    }
  };
}

function handle() {
  console.log(new Date());
}

window.addEventListener('scroll', throttle(handle, 1000));

Timeout

function throttle(func, delay) {
  let timer = null;

  return function(...args) {
    let context = this;

    if (!timer) {
      timer = setTimeout(function() {
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  };
}

function handle() {
  console.log(new Date());
}

window.addEventListener('scroll', throttle(handle, 1000));

Examples

Infinite scrolling

If the user is near the bottom, we should request via Ajax more content and append it to the page. We need to start fetching the content before the user reaches the bottom.

document.addEventListener('scroll', _.throttle(checkIfShowMore, 300));

function checkIfShowMore() {
  const docElement = document.documentElement;
  const documentHeight = docElement.scrollHeight;
  const windowHeight = docElement.clientHeight;
  const pixelsFromWindowBottomToBottom = 0 + documentHeight - window.scrollY - windowHeight;
}
rogerxu commented 5 years ago

requestAnimationFrame

requestAnimationFrame can be thought as a _.throttle(dosomething, 16). But with a much higher fidelity, since it's a browser native API that aims for better accuracy.

rogerxu commented 5 years ago

setInterval

注意点——setTimeout、setInterval使用 - 掘金

你真的了解setTimeout和setInterval吗? – 前端技术漫游指南

Scheduling: setTimeout and setInterval

Implementation

function run() {
  func.apply(context, args);

  setTimeout(function() {
    run();
  }, delay);
}

run();