単純に言えば、関数スロットリングは、非常に短い時間間隔内で連続的に呼ばれることができなくなります。あなたによって指定された時間間隔の後に最後の関数が実行された場合にのみ、関数への次の呼び出しを行うことができます。
関数スロットリングの原理は非常に簡単です。誰もがそれを考えていると思います、それはタイマーです。時間をトリガーするときは、最初にSetimoutを行い、実行する前にしばらくイベントを遅らせます。この時間間隔内にイベントが再度トリガーされた場合、元のタイマーをクリアしてから、しばらくの間実行を遅らせるために新しいタイマーを設定します。
次のシナリオでは、以下のシナリオは、DOM操作やリソースの読み込みなどの重い動作を行うことが多く、UIが一時停止したり、ブラウザのクラッシュさえします。
1。ウィンドウオブジェクトのイベントのサイズ変更とスクロール
2。ドラッグ中のMousemoveイベント
3。撮影ゲームでのムーズダウンイベントとキーダウンイベント
4。テキスト入力によって自動的に完了するキーアップイベント
実際、ウィンドウのサイズ変更イベントの場合、実際の要件は、サイズnミリ秒の変更を停止し、その後の処理を実行することです。他のほとんどのイベントでは、特定の周波数での後続の処理が必要です。これらの2つのニーズには、デバウンスとスロットルには2つのソリューションがあります。
スロットルとデバウンスは、リクエストと応答速度の不一致の問題を解決するための2つのソリューションです。 2つの間の違いは、異なる戦略を選択することにあります。
スロットルなどの間隔で関数を実行します。
イベントがデバウンス間隔t内で再度トリガーされた場合、停止時間がt以上になるまでタイマーが再チミングされます。
1。スロットル関数の簡単な実装
関数スロットル(FN、しきい値、スコープ){しきい値|| (閾値= 250); var last、タイマー。 return function(){var context = scope ||これ; var now = +new date()、args = arguments; if(last && now -last + thresthold <0){// cleartimeout(defertimer); Timer = setimeout(function(){last = now; fn.apply(context、args);}、したがって); } else {last = now; fn.Apply(Context、Args); }};}呼び出し方法
$( 'body')。on( 'mousemove'、throttle(function(event){console.log( 'tick');}、1000));2。デバウンス関数の簡単な実装
関数debounce(fn、delay){var timer = null; return function(){var context = this、args = arguments; ClearTimeout(タイマー); Timer = setimeout(function(){fn.apply(context、args);}、delay); };}呼び出し方法
$( 'input.username')。keypress(debounce(function(event){// ajax request}、250));3.簡単なパッケージングの実装
/**スロットル * @param fn、wait、debounce */var throttle = function(fn、wait、debounce){var timer = null、// timer t_last = null、// last time set、// context args、// parameter diff; //時間差はfunciton(){var curr = + new date(); var context = this、args = arguments; ClearTimeout(タイマー); if(debounce){// debounce timer = setimeout(function(){fn.apply(context、args);}、wait); } else {//スロットルの場合if(!t_last)t_last = curr; if(curr -t_last> = wait){fn.apply(context、wait);コンテキスト= wait = null; }}}}}/** * debounce * @param fn、wait */var debounce = function(fn、wait){return throttle(fn、wait、true);}概要:これらの2つの方法は、MouseMove、KeyDown、KeyUp、Keypress、Scrollなど、繰り返しトリガーされるイベントに適しています。
ネイティブイベントのみをバインドし、それらを制御しない場合、ブラウザはutter音を立て、ユーザーエクスペリエンスが低下します。 JSパフォーマンスを向上させるには、上記のイベントや同様のイベントを使用する際に制御するために、関数スロットリングまたは関数のデバウンスを使用することをお勧めします。
4。アンダースコアv1.7.0に関連するソースコードの分析
1。_.スロットル関数
_.throttle = function(func、wait、options){var context、args、result; var timeout = null; //タイマーvar forter = 0; //最後にトリガーされたif(!options)options = {}; var later = function(){previous = options.leading === false? 0:_.now();タイムアウト= null; result = func.apply(context、args); if(!timeout)context = args = null; }; return function(){var now = _.now(); // ifを実行するかどうか(!前&& options.leading === false)fortion = now; //残りの概念は次のとおりです。イベントを実行する時間はどれくらいですかvar残り= wait-(now -forter);コンテキスト= this; args = arguments; //残り<= 0イベントが停止した後にイベントが再試行されることを考慮して、または//待機が正確に異なる場合、イベントがすぐにトリガーされる//残り> wait){if(timeout){cleartimeout(timeout);タイムアウト= null; }前= now; result = func.apply(context、args); if(!timeout)context = args = null; //トラックするかどうか} else if(!timeout && options.trailing!== false){timeout = setimeout(後で、残り); } return result; };};上記からわかるように、Underscoreはより多くの状況を考慮しています。
初めて実行されると、デフォルトは真です。つまり、初めてが実行されます。初めて実行オプション。トレイングが無効になっている:最後の時間が実行されると、デフォルトは真であり、最後に実行されることを意味します。最後の時間は{Trailing:false}を意味します。つまり、最後の時間が実行されないことを意味します。いわゆる初めては、イベントが最初に実行されるかどうかです。イベントが開始されたばかりのとき、イベントを最初にトリガーするかどうか。必要に応じて、以前の= 0で、残りはネガティブで、関数が実行されたかどうかは前回、イベントが終わった後にすぐに呼び出されます。この方法は最後にトリガーされます。実行したい場合は、タイマーが設定されます。つまり、イベントが終了した後に1回実行する必要があります。レミアン>待機とは、クライアントの時間が変更されたことを意味します。
2。_.Debounce関数
_.debounce = function(func、wait、incime){//即時デフォルトはfalse var timeout、args、context、timestamp、resultです。 var later = function(){// _.debounceによって返される関数が待機で指定された時間間隔中に複数回呼び出されると、タイムスタンプの値は継続的に更新され、最後の<待機&& last> = 0は常に真実になります。 if(last <wait && last> = 0){timeout = setimeout(後で、待機 - 最後); } else {timeout = null; if(!intierm){result = func.apply(context、args); if(!timeout)context = args = null; }}}; return function(){context = this; args = arguments; timestamp = _.now(); //メソッドが最初に呼び出され、待機で指定された時間間隔の直後に、タイマーは(!Timeout)Timeout = setimeout(後で、待機)を使用する場合、FUNC関数を呼び出し始めます。 if(callnow){result = func.apply(context、args);コンテキスト= args = null; } return result; };};_.debounceの実装についての素晴らしいところは、ClearTimeoutを呼び出すことにより、func関数の呼び出しの遅延実行を調整する代わりに、タイマーを再帰的に開始することだと思います。
上記は、編集者が紹介したJavaScript Performance Optimization Function関数のスロットリングとデバウンス機能です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!