この記事は主に JS 関数のスロットリングと関数の揺れ防止の問題の分析を紹介しています。非常に優れており、必要な友人は参考にしてください。
質問 1: dom のドラッグ アンド ドロップ機能が実装されている場合。バインディングドラッグ時 イベントをドラッグすると、要素が少し動くたびに多数のコールバック関数がトリガーされ、ブラウザが直接フリーズしてしまうことがわかりました。この場合はどうすればよいでしょうか。
**質問 2:**ボタンがフォーム送信の投稿イベントにバインドされているが、ネットワーク状況が非常に悪い場合にユーザーがボタンを複数回クリックすることがあり、フォームが繰り返し送信される場合、どのようにすればよいですか?複数のコミットが発生しないようにするには?
上記のシナリオに対処するために、関数アンチシェイクと関数スロットルという 2 つの概念が登場しました。一般的に:
これら 2 つの方法は、タイムライン上の関数の実行回数を制御します。
関数 debounce(debounce)
コンセプト: イベントがトリガーされてから n 秒後にコールバックを実行します。この n 秒以内に再度トリガーされた場合は、時間を再開します。
実例: 誰かがエレベーターに入る(イベントをトリガーする)と、エレベーターは 10 秒後に出発します(イベントリスナーを実行します)。このとき、誰かがエレベーターに再び入ると(10 秒以内に再度イベントをトリガーします)。 、開始する前にさらに 10 秒待つ必要があります (タイミングを変更する)。
関数スロットル (スロットル)
概念: 単位時間を指定します。イベントが同じ単位時間内に複数回トリガーされた場合、イベントをトリガーするコールバック関数は 1 回だけ実行できます。回、1 つだけが有効になります。
生活の例: 現在の声明の 1 つは、1 秒以内に 24 枚以上の写真が連続して再生されると、人間の視覚の中で一貫したアニメーションが形成されるということです。したがって、映画の再生では (以前は、今はわかりませんが、基本的に 1 秒あたり 24 枚の画像が再生されるのはなぜでしょうか? 24 枚の画像で人間の視覚的ニーズを満たすことができるのに、100 枚の画像はリソースの無駄に見えるからです。
分析チャート
観測の合計時間が 10 秒で、イベントの最小間隔時間として 1 秒が指定されていると仮定します。
イベントのトリガー頻度が 0.5 秒/回の場合、手ぶれ補正機能は図のようになります
再度トリガーされるまで 1 秒待つことは決して不可能なので、最終的にはイベントは成功しません。
機能スロットリングは図の通り
最大で1秒に1回制御されるため、頻度は0.5s/回となり、1秒に1つのイベントが無効化されます。最終的な制御は 1 秒/時間です
イベントをトリガーする頻度が 2 秒/時間の場合、
関数手ぶれ補正は図に示すとおりです
2 秒/時間
はすでに指定された値より大きいため、最小時間なので、2 秒ごとに 1 回トリガーされます。
機能のスロットルは図に示すとおりです
同様に、2 秒/時間は最小時間要件より大きいため、すべてのトリガーが有効になります。
アプリケーション シナリオ
機能手ぶれ補正には、次のアプリケーション シナリオがあります:
フォームが複数回送信されるのを防ぐために、ボタンに手ぶれ補正機能を追加します。
入力ボックスへの連続入力に対してAJAX検証を実行する場合、関数アンチシェイクを使用すると、リクエストの数を効果的に減らすことができます。
スクロールが一番下にスライドしたかどうかを判断し、スクロールイベント+手ぶれ補正機能
一般に、一度に複数のイベントに応答するのに適しています
機能スロットルの場合、次のシナリオがあります:
ゲーム内のリフレッシュ レート
DOM 要素のドラッグ
キャンバス ブラシ機能
一般に、時間の経過とともに均等に分散された多数のイベントをトリガーするのに適しています。
ソースコード
関数手ぶれ補正:
function debounce(fn, wait) { var timer = null; return function () { var context = this var args = arguments if (timer) { clearTimeout(timer); timer = null; } timer = setTimeout(function () { fn.apply(context, args) }, wait) } } var fn = function () { console.log('boom') } setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,之后每1000ms触发一次 setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)
なぜ関数を返すかというと、手ぶれ補正自体が関数の修正に近いため、関数のカリー化が行われています。クロージャも使用されており、クロージャの変数はタイマーです。
機能制限
function throttle(fn, gapTime) { let _lastTime = null; return function () { let _nowTime = + new Date() if (_nowTime - _lastTime > gapTime || !_lastTime) { fn(); _lastTime = _nowTime } } } let fn = ()=>{ console.log('boom') } setInterval(throttle(fn,1000),10)
写真は、実装された簡単な機能制限を示しています。その結果、1秒に1回のブームが発生しました
上記は、将来皆さんの役に立てば幸いです。 。
関連記事:
以上がJS での関数スロットルと関数アンチシェイクについて (詳細なチュートリアル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。