デローディングとスロットル

15504 ワード

debouncing


連続呼び出しの関数の最後の呼び出しの関数のみを実行します.
主にajax検索に使用されます.APIリクエストは、自動完了などの特定の文字列の入力が完了した場合にのみ送信されます.
ダイヤルバック機能を使わずに検索を使うとどうなりますか?

1文字ずつ入力すると、いくつかの文字が入力されていることが表示されます.
この場合、これはあまり影響しませんが、APIリクエストを送信する操作であれば?
要求を送信し続けるため、不要な要求が送信される可能性があります.



上に表示されている1文字を入力するたびに、何文字を入力したかを教えてくれます.
エスケープを使用すると、1秒以内に入力がない場合、何文字入力したかを示す文字が表示されます.
const debounce = (fn, delay) => {
  let timer;

  return () => {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn();
      setTimeout(() => {
        notice.innerHTML = "";
      }, delay);
    }, delay);
  };
};

inputElement.addEventListener(
  "input",
  debounce(() => {
    notice.innerHTML = `${inputElement.value.length}자 입력 완료`;
  }, 1000)
);
モジュールを用いてdebonse関数を実現した.関数を返し、inputイベントが実行されるたびに関数が返されることを確認します.
入力ウィンドウで文章を作成するときにtimer変数に値がある場合は、cleartimeoutでtimerをクリアし、新しいtimerを生成します.
入力が完了すると、settimeoutのコールバック関数が実行され、必要な操作が実行されます.
これを利用してAJAXリクエストを送信できます.
getMovies関数を実現し、単語を入力してその単語を含む映画のリストを返します.
const getMovies = async () => {
  try {
    const movieName = inputElement.value;
    const result = await fetch(
      `https://api.tvmaze.com/search/shows?q=${movieName}`
    );
    const response = await result.json();

    const movieList = response.map((data) => ({
      id: data.show.id,
      name: data.show.name,
      url: data.show.image?.medium
    }));

    return movieList;
  } catch (e) {
    console.error(e.message);
  }
};
const onInput = async () => {
  const movieList = await getMovies();
  notice.innerHTML = "";
  movieList.map(
    (movie) =>
      (notice.innerHTML += `<li key=${movie.id}>
          ${movie.name}
          <img src=${movie.url} />
	</li>`)
  );
};

inputElement.addEventListener("input", debounce(onInput, 2000));

このように文字を入力する場合、apiリクエストは送信されず、一定期間入力されていない場合、apiリクエストを送信することができる.

throttling


最後の関数が呼び出されてからしばらくの間、関数は呼び出されません.
通常、スクロールイベントの処理に使用されます.スクロールまたはアップロード時に大量のイベントが実行されます.
降りるたびにイベントがあります.

制限を使用して、イベント呼び出しを最小限に抑えます.



スクロールするたびにイベントを実行するのではなく、指定した時間後に関数を呼び出します.
これにより、不要なイベント呼び出しが減少します.
const throttle = (fn, delay) => {
  let timer;

  return () => {
    if (!timer) {
      timer = setTimeout(() => {
        timer = null;
        fn();
      }, delay);
    }
  };
};

window.addEventListener(
  "scroll",
  throttle(() => {
    const scrollY = window.scrollY;
    console.log(`scrollY : ${scrollY}`);
  }, 500)
);
debonseと同様にモジュールを用いてthrottle関数を実現した.
timerが存在しない場合はsettimeoutを作成し、timer変数に挿入します.その後、一定時間経過した後、timerを初期化し、伝達された関数を実行します.