JavaScript におけるタイマーの原理の分析

黄舟
リリース: 2017-11-18 13:53:48
オリジナル
1611 人が閲覧しました

私たちの仕事に携わる多くの人は、javascriptタイマーについて話すとき、setTimeout()とsetInterval()という2つの関数を思い浮かべるでしょうが、彼らはJavaScriptにおけるタイマーの原理が何であるかを知りません。イベントからスタートタイマー機能の動作原理と違いをイベントループの視点から分析!

setTimeout()

MDN は、setTimeout を次のように定義します。

指定された遅延時間の後に関数を呼び出すか、コードフラグメントを実行します。

構文

setTimeout の構文は非常に単純で、最初のパラメーターは コールバック関数 で、2 番目のパラメーターは遅延時間です。この関数は、数値型の一意の識別子を返します。この ID は、タイマーをキャンセルするために、clearTimeout のパラメーターとして使用できます。

var timeoutID = window.setTimeout(code, delay);
ログイン後にコピー

IE0+ は、コールバック パラメーターの受け渡しもサポートしています:

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
ログイン後にコピー

setInterval()

。 MDN Right setInterval の定義は次のとおりです:

定期的に関数 (関数) を呼び出すか、コードを実行します。

setInterval と setTimeout の使用法は同じであるため、ここにはリストされていません。

第二引数(遅延)の説明

JavaScriptのイベントループの仕組み上、第二引数は遅延ミリ秒後にコールバック関数を即実行するのではなく、イベントキューにコールバック関数を追加しようとします。実際、この時点で setTimeout と setInterval の処理には違いがあります。

  • setTimeout: 遅延ミリ秒が経過すると、何があってもコールバック関数がイベント キューに直接追加されます。

  • setInterval: ミリ秒の遅延の後、まずイベントキューにまだ実行されていないコールバック関数 (setInterval のコールバック関数) があるかどうかを確認します。存在する場合は、イベントにコールバック関数を追加しないでください。列。

そのため、コード内に時間のかかるタスクがある場合、タイマーは想定どおりに動作しません。

例を通して次のコードを理解しましょう。当初は 100 ミリ秒と 200 ミリ秒でコールバック関数を呼び出せることを期待していました (つまり、100 ミリ秒待つだけです):

var timerStart1 = now();
setTimeout(function () {
 console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);
 var timerStart2 = now();
 setTimeout(function () {
  console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
 }, 100);
}, 100);
// 输出:
// 第一个setTimeout回调执行等待时间: 106
// 第二个setTimeout回调执行等待时间: 107
ログイン後にコピー

この結果は、私たちが考えていたものとまったく同じです。時間のかかるタスクをコードに追加しましたが、結果は期待したものではありませんでした:

var timerStart1 = now();
setTimeout(function () {
 console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);

 var timerStart2 = now();
 setTimeout(function () {
  console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
 }, 100);

 heavyTask(); // 耗时任务
}, 100);

var loopStart = now();
heavyTask(); // 耗时任务
console.log('heavyTask耗费时间:', now() - loopStart);

function heavyTask() {
 var s = now();
 while(now() - s < 1000) {
 }
}

function now () {
 return new Date();
}
// 输出:
// heavyTask耗费时间: 1015
// 第一个setTimeout回调执行等待时间: 1018
// 第二个setTimeout回调执行等待时间: 1000
ログイン後にコピー

時間のかかるタスクの存在により、2 つの setTimeout 待機イベントは 100 ミリ秒ではなくなりました。何が起こったのか説明しましょう:

まず、時間のかかる最初のタスク (heavyTask()) が実行を開始し、完了するまでに約 1000 ミリ秒かかります。
  1. 100ms 後、最初の setTimeout コールバック関数が実行されると予想されるため、イベント キューに追加されますが、前の時間のかかるタスクはまだ実行されていません。したがって、キュー内で待機することしかできず、時間のかかるタスクが完了するまで実行は開始されません。そのため、結果には次のように表示されます。最初の setTimeout コールバック実行待機時間: 1018。
  2. 最初の setTimeout コールバックが実行されるとすぐに、このタイマーも 100 ミリ秒の遅延後にコールバック関数を実行することが期待されます。 ただし、最初の setTimeout には別の時間のかかるタスクがあり、そのプロットは最初のタイマーと同じであり、実行を開始する前に 1000 ミリ秒待機します。
  3. は次の図で要約できます:

setInterval の例を見てみましょう:

var intervalStart = now();
setInterval(function () {
 console.log(&#39;interval距定义定时器的时间:&#39;, now() - loopStart);
}, 100);
var loopStart = now();
heavyTask();
console.log(&#39;heavyTask耗费时间:&#39;, now() - loopStart);
function heavyTask() {
 var s = now();
 while(now() - s < 1000) {
 }
}
function now () {
 return new Date();
}
// 输出:
// heavyTask耗费时间: 1013
// interval距定义定时器的时间: 1016
// interval距定义定时器的时间: 1123
// interval距定义定时器的时间: 1224
ログイン後にコピー
上記のコードでは、100 ミリ秒ごとにログを出力することを想定しています。 setTimeout と比較すると、setInterval は、イベント キューにコールバック関数を追加する準備をするときに、キューに未実行のコールバックがあるかどうかを判断します。ある場合は、コールバック関数をキューに追加しません。 それ以外の場合、複数のコールバックが同時に実行されます。

は次の図で要約できます:

要約:

上記で、JavaScript タイマーの実行原理を簡単に分析しました。誰もが JavaScript の動作原理を理解していると思います。タイマーについてはある程度理解できましたので、お役に立てれば幸いです。

関連する推奨事項:

JavaScript タイマーのサンプル コード

JavaScript タイマーの詳細な探索

JavaScriptタイマーの完全な例

JavaScriptタイマーと最適化されたキャンセルタイマーメソッド

以上がJavaScript におけるタイマーの原理の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート