[javascript deepdave]41枚のタイマー


41.1コールスケール


関数を明示的に呼び出さず、一定時間後に関数呼び出しを予定する場合は、呼び出しスケジューリング(sheduling a call)と呼ばれるタイミング関数が使用されます.タイマ関数は、ECMAScript仕様で定義されているビルダーではありませんが、ブラウザ環境とノードにあります.js環境では、タイマ関数をグローバルオブジェクトとして使用する方法が提供されています.すなわち、タイマ関数はホストオブジェクトである.settimeout(1回の呼び出し)とsetInterval(期限切れのたびに)は、一定時間後にコールバック関数を呼び出してタイマを生成します.
JavaScriptエンジンには実行コンテキストスタックがあるため、2つ以上のタスクを同時に実行することはできません.すなわちjavascriptは単一スレッド(singlethread)を用いて動作する.したがって、タイマ関数は非同期(非同期)処理で動作する.

41.2タイマ関数


41.2.1 setTimeout/clearTimeout


settimeout関数は、2番目の引数が伝達される時間で1回の操作を行うタイマを生成します.その後、タイマが期限切れになると、最初のパラメータとして渡されるコールバック関数が呼び出されます.
const timeoutId = setTimeout(name => console.log(`Hi! ${name}`),1000,'Lee');
1초(1000ms) 후 타이머가 만료되면 콜백함수가 호출되며 Lee가 인수로 전달된다. 
settimeout関数は、生成されたタイマを識別できる一意のタイマidを返す.ブラウザ環境がそうである場合、返されるタイマidは数値です.Node.jsの場合はオブジェクトです.このidはcleartimeout関数のパラメータとして渡すことができ、タイマをキャンセルします.clearTimeoutコールスケジュールをキャンセルします.

41.2.2 setInterval / clearInterval


setInterval関数は、2番目の引数が伝達される時間(ミリ秒、1/1000秒)で動作を繰り返すタイマを生成します.後で期限が切れるたびに、parameterに渡されるコールバック関数がキャンセルされるまで繰り返し呼び出されます.setInterval関数は、生成されたタイマを識別できる一意のタイマidも返す.ブラウザ環境がそうである場合、返されるタイマidは数値です.Node.jsの場合はオブジェクトです.このidはcleartimeout関数のパラメータとして渡すことができ、タイマをキャンセルします.clearTimeoutコールスケジュールをキャンセルします.

41.3ジッタと制限


スクロール、サイズ変更、入力、mousemoveなどのイベントは、短い時間間隔で連続的に発生します.これらのイベントにバインドされたイベントハンドルが過度に呼び出され、問題が発生する可能性があります.ホップバックとトラッキングは、短時間間隔で連続的に発生するイベントを防止し、過剰なイベントハンドラ呼び出しを防止するプログラミング技術である.

41.3.1ジッタ


イベントが短時間間隔で連続して発生する場合、デバッガはイベントハンドラを呼び出さないが、一定時間後にはイベントハンドラを呼び出すのは1回だけである.短時間間隔で発生するイベントをグループ化し、最後に1回だけ呼び出す.
たとえば、テキスト入力フィールドでは、入力イベントが短い時間間隔で連続的に発生する場合があります.ユーザーがテキスト入力フィールドに値を入力するたびにinputイベントが連続して発生します.
Inputのイベントハンドラがユーザが入力フィールドに入力した値でAjax要求などの煩雑な処理を実行すると、ユーザが入力を完了していなくても、Ajax要求は送信され続けます.これはサーバに負担をかける不要な処理であるため,ユーザが入力を完了した場合には,Ajaxリクエストを一度だけ送信することが望ましい.

ユーザーが入力を完了したかどうかを判断できないため、入力フィールドに値が入力されていない場合は、入力が完了したとみなされます.このため、debonse関数が返す関数は、前のタイマをキャンセルし、イベントが発生した時間間隔が2番目のパラメータが伝達する時間間隔(delay)より小さい場合、新しいタイマを設定します.したがって、delayよりも短い間隔でイベントが連続的に発生すると、debonse関数の最初のパラメータとして渡されるコールバック関数は呼び出されず、delayの間に入力イベントが発生しない限り、一度だけ呼び出されます.

イベントがこのような短い時間間隔で連続的に発生する場合、イベントハンドラを呼び出さずにイベントハンドラを呼び出さず、イベントハンドラを呼び出さずに1回だけ呼び出すと、resizeイベント処理またはinput要素に入力された値要求ajaxの入力フィールドが自動的に完了する.UI実装;ボタン重複クリック防止処理などに使用できます.
上の例題は不完全だ.実際の操作では、下線のdebonse関数またはlodashのdebonse関数を使用することを推奨します.

41.3.2制限


連続して発生するイベントを短い時間間隔でグループ化することを制限し、イベントハンドラを一定時間呼び出すための呼び出しサイクルを作成します.
const $container = document.querySelector('.container');
const $normalCount = document.querySelector('.normal-count');
const $throttleCount = document.querySelector('.throttle-count');

const throttle = (callback, delay) => {
    let timerId;
    return event => {
        if (timerId) return;
        timerId = setTimeout(() => {
            callback(event);
            timerId = null;
        }, delay,event);
    };
};

let normalCount = 0;
$container.addEventListener('scroll',() => {
    $normalCount.textContent = ++$normalCount;
});

let throttleCount = 0;
$container.addEventListener('scroll', throttle(()=>{
    $throttleCount.textContent = ++ throttleCount;
}),100)

スクロールイベントは、ユーザーがスクロールするときに連続して発生します.このような短い時間間隔で連続的に発生するイベントに対して過剰なイベントハンドラが呼び出されないように、throttle関数はイベントをグループ化し、イベントハンドラを一定時間呼び出すための呼び出しサイクルを作成します.
throttle関数が返す関数は、2回目の伝達時間の前にイベントが発生した場合は何も実行されません.遅延時間が発生した場合はコールバック関数を呼び出し、新しいタイマを再設定します.したがって、遅延時間間隔でコールバック関数が呼び出される.したがって,スクロールイベントの処理,無限スクロールの実現などに用いることが制限される.これもベースラインスコアやロダッシュの関数を使用しています.
read me 
1103 : 업로드