この記事では主に、JS 関数のデバウンスとスロットルの知識の詳細な分析と、JS コードの分析について紹介します。JS に興味がある友人は参考として読んでください。
この記事では、スロットリングとデバウンスの基本的な概念から始まり、JS 関数の詳細な分析を行います。
1. スロットルとデバウンスとは何ですか?
倹約。蛇口を締めるだけで水の流れは少なくなりますが、水の流れは止まりません。現実の生活では、水を汲むためにバケツに水を汲む必要がある場合があると想像してください。私たちは、何か他のことをするためにずっとそこに立って待っていたくありません。再び戻ってくるときに、水がバケツにいっぱいになるようにしてください。そうしないと、戻ってくる前に水がいっぱいになり、大量の水を無駄にすることになります。戻ってくるときに水がほぼ満タンになるようにスロットルを下げる必要があります。では、JS にはそのような状況があるのでしょうか? 典型的なシナリオは、画像の遅延読み込みとページの scoll イベントの監視、またはマウスの mousemove イベントの監視です。 Mousemove はマウスが移動するときに使用され、ブラウザによって頻繁にトリガーされるため、対応するイベントが頻繁にトリガーされ (水の流れが速すぎる)、ブラウザーのリソースに多くのオーバーヘッドが発生します。中間処理は不要です。このとき、スロットリングする必要があります。ブラウザーが対応するイベントをトリガーするのを防ぐことはできませんが、イベントを処理するメソッドの実行頻度を減らすことはでき、それによって対応する処理のオーバーヘッドを減らすことができます。
揺れを解消します。私がこの用語を初めて知ったのはおそらく高校の物理でした。スイッチが実際に閉じる前にジッターが発生する場合があります。その場合、対応する小さな電球が点滅しても問題はありません。この時、また目にダメージを受けると厄介です。このページでも、ユーザーがコンテンツを入力しているときに、入力ボックスの 1 つがバックグラウンドで対応する単語をクエリすると、入力イベントが頻繁にトリガーされ、その後、逆方向にクエリが実行されるとします。リクエストが発生すると、ユーザーの入力が完了するまで前のリクエストは冗長である必要があります。ネットワークが遅く、バックグラウンドから返されるデータが遅いと仮定すると、表示される関連単語は最後のリクエストが返されるまで頻繁に変更される可能性があります。このとき、一定時間内に再度入力するかどうかを監視し、再度入力がない場合は入力が完了したものとみなし、リクエストを送信します。まだ入力中のため、リクエストは送信されません。
デバウンスとスロットルは異なります。スロットルは中間処理関数を制限しますが、周波数を下げるだけですが、デバウンスはすべての中間処理関数を除外し、指定された時間内のタスクのみを実行します。
2. JS実装。
これまで多くのことを述べてきましたが、辛抱強く読んでいただきありがとうございます。スロットルとデバウンスを自分で実現する方法を見てみましょう。
スロットリング:
/** 实现思路: ** 参数需要一个执行的频率,和一个对应的处理函数, ** 内部需要一个lastTime 变量记录上一次执行的时间 **/ function throttle (func, wait) { let lastTime = null // 为了避免每次调用lastTime都被清空,利用js的闭包返回一个function确保不生命全局变量也可以 return function () { let now = new Date() // 如果上次执行的时间和这次触发的时间大于一个执行周期,则执行 if (now - lastTime - wait > 0) { func() lastTime = now } } }
呼び出し方法を見てみましょう:
// 由于闭包的存在,调用会不一样 let throttleRun = throttle(() => { console.log(123) }, 400) window.addEventListener('scroll', throttleRun)
この時点で、ページをめちゃくちゃにスクロールすると、123 が 4 に出力されることがわかります。 00ミリ秒ただし、スロットルを設定しないと連続的に印刷されます。待機パラメータを変更して違いを感じることができます。
しかし、ここで、私たちのスロットルメソッドは不完全です。なぜなら、私たちのメソッドは、イベントの発生時にこのオブジェクトを取得しないからです。また、私たちのメソッドは、このトリガーと最後の実行の時間を判断することによって単純かつ粗雑であるためです。時間間隔は、次のことを決定します。コールバックを実行すると、最後のトリガーが実行できなくなるか、ユーザーの出発間隔が実際に非常に短く実行できず、過失致死が発生するため、メソッドを改善する必要があります。
function throttle (func, wait) { let lastTime = null let timeout return function () { let context = this let now = new Date() // 如果上次执行的时间和这次触发的时间大于一个执行周期,则执行 if (now - lastTime - wait > 0) { // 如果之前有了定时任务则清除 if (timeout) { clearTimeout(timeout) timeout = null } func.apply(context, arguments) lastTime = now } else if (!timeout) { timeout = setTimeout(() => { // 改变执行上下文环境 func.apply(context, arguments) }, wait) } } }
このようにして、私たちのメソッドは比較的完成しており、呼び出しメソッドは以前と同じです。
デバウンス:
デバウンス メソッドはスロットリングと一致しますが、このメソッドはジッターが終了したと判断された後にのみ実行されます。
debounce (func, wait) { let lastTime = null let timeout return function () { let context = this let now = new Date() // 判定不是一次抖动 if (now - lastTime - wait > 0) { setTimeout(() => { func.apply(context, arguments) }, wait) } else { if (timeout) { clearTimeout(timeout) timeout = null } timeout = setTimeout(() => { func.apply(context, arguments) }, wait) } // 注意这里lastTime是上次的触发时间 lastTime = now } }
このとき、先ほどと同じ方法で呼び出してみると、ウィンドウをどれだけスクロールしても、スクロールを止めたときにのみ対応するイベントが実行されることがわかります。
デバウンスとスロットリングは多くの成熟した JS によって実装されており、一般的なアイデアは基本的に次のとおりです。
ネチズンの実装メソッドのコードを共有しましょう:
メソッド 1
1. この実装メソッドのアイデアは理解しやすいです: 50 などの間隔を設定します。ミリ秒、から この時間はベースライン設定 タイマー です。最初のトリガー イベントと 2 番目のトリガー イベントの間の間隔が 50 ミリ秒未満の場合は、このタイマーをクリアして新しいタイマーを設定し、イベントがトリガーされるまでこれを繰り返します。最後の 50 ミリ秒以内に再トリガーはありません。コードは次のとおりです:
function debounce(method){ clearTimeout(method.timer); method.timer=setTimeout(function(){ method(); },50); }
这种设计方式有一个问题:本来应该多次触发的事件,可能最终只会发生一次。具体来说,一个循序渐进的滚动事件,如果用户滚动太快速,或者程序设置的函数节流间隔时间太长,那么最终滚动事件会呈现为一个很突然的跳跃事件,中间过程都被节流截掉了。这个例子举的有点夸张了,不过使用这种方式进行节流最终是会明显感受到程序比不节流的时候“更突兀”,这对于用户体验是很差的。有一种弥补这种缺陷的设计思路。
方法二
2.第二种实现方式的思路与第一种稍有差别:设置一个间隔时间,比如50毫秒,以此时间为基准稳定分隔事件触发情况,也就是说100毫秒内连续触发多次事件,也只会按照50毫秒一次稳定分隔执行。代码如下:
var oldTime=new Date().getTime(); var delay=50; function throttle1(method){ var curTime=new Date().getTime(); if(curTime-oldTime>=delay){ oldTime=curTime; method(); } }
相比于第一种方法,第二种方法也许会比第一种方法执行更多次(有时候意味着更多次请求后台,即更多的流量),但是却很好的解决了第一种方法清除中间过程的缺陷。因此在具体场景应根据情况择优决定使用哪种方法。
对于方法二,我们再提供另一种同样功能的写法:
var timer=undefined,delay=50; function throttle2(method){ if(timer){ return ; } method(); timer=setTimeout(function(){ timer=undefined; },delay); }
以上就是本文的所有内容,希望会给大家带来帮助!!
相关推荐:
以上がJS関数のデバウンスとスロットルの詳細分析_基礎知識の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

メモ帳++7.3.1
使いやすく無料のコードエディター

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ドリームウィーバー CS6
ビジュアル Web 開発ツール
