ホームページ >ウェブフロントエンド >jsチュートリアル >タイムアウトを設定する必要はありません

タイムアウトを設定する必要はありません

WBOY
WBOYオリジナル
2024-08-12 19:02:36706ブラウズ

タイマーは、しばらくの間、多くの人が日常業務で使用する機能であることは知っています。 JavaScript の世界では、タイマーは setTimeout 関数または setInterval 関数を使用して実装されることがよくありますが、それを実行している場合に悪い知らせは、それが良い習慣ではないということです。その理由を説明します。

私の考えを説明する前に、あなたに質問があります: 間違った時間を知らせる時計を使用できますか?

あなたの答えが「はい」の場合、この記事はあなたのものではないため、貴重な時間を無駄にして申し訳ありません。

一方、答えが否定的であれば、setTimeout または setInterval を使用することが、時間を取得するために破損した時計を使用するようなものである理由を説明します。

これらの機能の問題点

まず、次のスニペットについて考えてみましょう

 function test() {
   let i = 0;
   setTimeout(() => console.log("hello"), 0);
   while (i < 5) {
     console.log("number ", i);
     i += 1;
  }
  console.log("world");

ブラウザ コンソールでこのスニペットを実行すると、次の結果が得られます

You don&#t need to set the time-out

この動作は、setTimeout がブラウザのキューにコールバックを追加しているため、アイドル状態になったら処理する必要があります (実行するタスクがない)、つまりコールバックsetTimeout に渡されるものは優先度が低い

これを理解すると、setTimeout 関数を使用してタイマーを実装するのは難しいと思います。なぜなら、同時に 2 ティック、場合によっては 10 ティック (ブラウザーのビジー度に応じて) を設定できるためです。これをデバッグするのは悪夢のようですが、もっと良い解決策はありますか?

これらの機能を回避する方法

タイマーを実装するより良い方法を提供するには、requestAnimationFrame 関数を使用する必要があります。この関数は、ブラウザに次のペイントの前にコールバックを実行するよう指示するためです(つまり、UI の変更が発生する前)

ここでの違いは非常に微妙なので、コードを通して理解することをお勧めします。以前のスニペットを元に戻し、setTimeout と requestAnimationFrame
を比較するために少し調整してみましょう。

function testWithAnimationFrame() {
  let i = 0;
  setTimeout(() => console.log("hello"), 0);
  requestAnimationFrame(() => console.log("tell me the next paint"));
  while (i < 5) {
    console.log("number ", i);
    i += 1;
  }
  console.log("world");
}

この例では、Chrome で実行すると、setTimeout が requestAnimationFrame より前に実行されることがわかります (ただし、まれに逆の場合もあります)

You don&#t need to set the time-out

ただし、Firefox で実行すると、次の出力が表示されます

You don&#t need to set the time-out

これはややこしいように思えるかもしれませんが、少し注意してみると、実行中に描画が行われていないことがわかります。そのため、このシナリオがどのように処理されるかはブラウザによって異なります。

ここでスニペットを調整してブラウザにページを再描画させることができたら、何が起こるか見てみましょう

function testWithAnimationFrame2() {
  let i = 0;
  setTimeout(() => console.log("hello"), 0);
  requestAnimationFrame(() => console.log("tell me the next paint"));
  while (i < 5) {
    console.log("number ", i);
    i += 1;
    document.body.style.backgroundColor = "red";
  }
  console.log("world");
}

Chrome での出力は次のとおりです

You don

Firefox での出力は次のとおりです

You don

ログでわかるように、ブラウザーが UI に変更を加えると、requestAnimationFrame 関数が他のスケジュールされたコールバックよりも常に優先されます。

Web では常に再描画が実行されるため、タイマーを実装するには requestAnimationFrame を選択するのが当然です。

requestAnimationFrame 関数を理解する

関数はパラメータとしてコールバックのみを受け取ります。コールバックにコンテキストを提供するには、ページの最初のレンダリングの時間に基づいて、前のフレームが終了した時間を示すタイムスタンプを取得する必要があります。

この関数はリクエストの識別子を表す整数を返します。これは、cancelAnimationFrame 関数でリクエストをキャンセルしたい場合に便利です。

JavaScript でのストップウォッチの簡単な実装

ストップウォッチを実装するには、いくつかの要件があります:

  • どのくらいの時間経過したら (通常は 1 秒) を知る必要があります
  • ストップウォッチが停止するまでの遅延時間を知る必要があります
  • カチカチ音を立てる間隔は遅延よりも短くする必要があります

これらすべての要件を考慮して、次のコード スニペットによりストップウォッチが作成されます

アウトロ

長々と読んだかもしれませんが、楽しんでいただけたと思います。とにかく、ご質問やご提案がございましたら、お気軽にご連絡ください。

お読みいただきありがとうございます。それではさようなら?

以上がタイムアウトを設定する必要はありませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。