非同期性

Frontend SELF JA
レベル 43 , レッスン 0
使用可能

1.1 非同期性の基本概念

JavaScriptの非同期性は、メインスレッドをブロックせずにバックグラウンドでタスクを実行することを可能にします。 ネットワークリクエストやファイルの読み取り、タイマーのような時間がかかるかもしれないタスクに特に重要です。 ここでは、JavaScriptの非同期プログラミングの基本的な概念を紹介し、その使用例を示します。

JavaScriptのシングルスレッド特性

JavaScriptはシングルスレッド言語です。つまり、一つのスレッドでコードを順次実行します。 しかし、非同期操作により、バックグラウンドでタスクを実行し、メインスレッドを他のタスクに利用可能にします。

Event Loop (イベントループ)

イベントループは、JavaScriptが非同期タスクを処理するための重要なメカニズムです。 イベントループはメッセージキュー(Message Queue)とマイクロタスクキュー(Microtask Queue)を管理し、 非同期操作の実行を保証します。

  1. メッセージキュー: イベントハンドラーやネットワークリクエスト、タイマーなどのタスクを含みます。このキューのタスクは順次実行されます。
  2. マイクロタスクキュー: メッセージキュー内のタスクよりも高い優先度を持つタスクを含みます。例としては、Promiseの完了やコールバックの呼び出しなどがあります。

イベントループは両方のキューを常にチェックし、メインスレッドが空いたときにタスクを実行します。

非同期操作

非同期操作はバックグラウンドでタスクを実行することを可能にします。主な非同期操作の例には以下があります:

  • タイマー (setTimeout, setInterval)
  • イベントハンドラー
  • ネットワークリクエスト (例: XMLHttpRequest, Fetch API)
  • ファイルの読み書き (Node.jsで)

非同期操作のいくつかの例を見ていきましょう。

1.2 タイマー

タイマーは、遅延や定期的な間隔でタスクを実行することを可能にします。

setTimeoutの使用例

この例では、setTimeoutが2秒後に関数を実行するように設定されています。結果として、StartEndが最初に表示され、 その後2秒後にExecuted after 2 secondsが表示されます。

JavaScript
    
      console.log('Start');

      setTimeout(() => {
        console.log('Executed after 2 seconds');
      }, 2000);

      console.log('End');
    
  

setIntervalの使用例

この例では、setIntervalが関数を1秒ごとに実行し、カウンタを増加させてその値を出力します。 カウンタが5に達すると、clearIntervalを使ってインターバルが解除されます:

JavaScript
    
      let counter = 0;

      const intervalID = setInterval(() => {
        counter++;
        console.log(`Counter: ${counter}`);
        if (counter >= 5) {
          clearInterval(intervalID);
        }
      }, 1000);
    
  

1.3 イベントハンドラー

イベントハンドラーは、ユーザーの操作やその他のイベントに応答してコードを実行します。

イベントハンドラーの使用例

この例では、clickイベントハンドラーがボタンに追加されており、ユーザーがボタンをクリックすると Button clicked!というメッセージが表示されます:

HTML
    
      <!DOCTYPE html>
      <html>
        <head>
          <title>Event Handler Example</title>
        </head>
        <body>
          <button id="myButton">Click me</button>

          <script>
            const button = document.getElementById('myButton');

            button.addEventListener('click', () => {
              console.log('Button clicked!');
            });
          </script>
        </body>
      </html>
    
  

1.4 ネットワークリクエスト

ネットワークリクエストは、サーバーへの非同期HTTPリクエストを実行することを可能にします。

XMLHttpRequestの使用例

この例では、APIへの非同期GETリクエストを作成し、リクエストが完了すると、レスポンスをコンソールに出力します:

JavaScript
    
      const xhr = new XMLHttpRequest();
      xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);

      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
          const response = JSON.parse(xhr.responseText);
          console.log(response);
        }
      };

      xhr.send();
    
  

1.5 イベントループの動作

イベントループの動作をよりよく理解するために、次の例を見てみましょう:

JavaScript
    
      console.log('Start');

      setTimeout(() => {
        console.log('Timeout 1');
      }, 0);

      Promise.resolve().then(() => {
        console.log('Promise 1');
      });

      setTimeout(() => {
        console.log('Timeout 2');
      }, 0);

      Promise.resolve().then(() => {
        console.log('Promise 2');
      });

      console.log('End');
    
  

予想される出力は以下のとおりです:

  • Start
  • End
  • Promise 1
  • Promise 2
  • Timeout 1
  • Timeout 2

この例では、まず同期操作が実行されます (console.log('Start') および console.log('End'))。次に マイクロタスク (Promiseハンドラー) が実行され、その後でメッセージキューのタスク (setTimeout) が実行されます。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION