0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】非同期処理① 〜同期処理・非同期処理〜

Posted at

概要

JavaScriptを学習、理解を深めるため「JavaScript Primer 迷わないための入門書」を読み、
理解した内容等を記載していく。

【JavaScript】JavaScript入門一覧」に他の記事をまとめています。

この記事で理解できること

  • 同期処理と非同期処理について
  • 非同期処理における例外発生時の挙動

多くのプログラミング言語にはコードの評価の方法として
同期処理(sync)」「非同期処理(async)」という大きな分類がある。

同期処理

  • コードを上から順番に処理する(処理1 -> 処理2 -> 処理3...)
  • 一つの処理が終わるまで次の処理は行われない。
// 同期的な処理
console.log("処理1");
console.log("処理2");
console.log("処理3");
// => 処理1
// => 処理2
// => 処理3

JavaScriptにおける同期的処理の懸念点

  • JavaScriptは基本的にブラウザのメインスレッド(UIスレッドとも呼ばれる)で処理が実行される。
  • メインスレッドは表示の更新といったUIに関する処理などを行なっている。
  • その為、メインスレッドが何らかの処理で専有されると、表示がフリーズしたかのような現象が起こる。

※以下のサンプルコードの内容を「index.html」のようなファイル名で保存し、ブラウザで開いてみてください。
※ボタン押下前はホバー時の色の変化が確認が可能ですが、ボタン押下後、3秒間フリーズしたかのような状態になります。

サンプルコード
<html>
  <style>
    button {
      padding: 25px;
      border: none;
      background: #e5b6e2;
    }
    button:hover {
      background: #dec8dd;
    }
  </style>
<body>
  <button type="button" onclick="block()">ボタン</button>

  <script>
    // ボタンをクリックした際に呼び出される関数
    function block() {
      console.log("clickButton");
      blockFunc(3000);
    }

    // 処理を指定時間ブロックする処理
    function blockFunc(time) {
      const startTime = Date.now();

      while (true) {
        const diffTime = Date.now() - startTime;
        if (diffTime >= time) {
          return;
        }
      }
    }
  </script>
</body>
</html>

非同期処理

  • 同期処理とは異なり、一つの処理が終わるのを待たずに次の処理も実行する。
  • つまり、非同期処理では同時に実行している処理が複数ある。
// 非同期処理の代表的な関数、setTimeout関数を使用する

function asyncFunc() {
  console.log('処理1を始めます');

  // 仮想的に処理1を5秒かかることにする
  setTimeout(() => {
    console.log('処理1が終わりました');
  }, 5000);

  // 並行して処理2を開始
  console.log('処理2を始めます');
   // 仮想的に処理2を3秒かかることにする
  setTimeout(() => {
    console.log('処理2が終わりました');
  }, 3000);
}

asyncFunc();
// => 処理1を始めます
// => 処理2を始めます
// ...3秒後
// => 処理2が終わりました
// その2秒後(計5秒後)
// => 処理1が終わりました

上記が同期的処理であった場合は、以下のように上から順に処理が行われていたはず。

// ...省略

asyncFunc();
// => 処理1を始めます
// => 処理1が終わりました
// => 処理2を始めます
// => 処理2が終わりました

非同期処理と例外処理

  • 非同期処理では、try...catch構文を使っても非同期的に発生した例外をキャッチできない。
  • また、非同期処理の外からは非同期処理の中で例外が発生したかがわからない
  • そのため、非同期処理の中で例外が発生したことを非同期処理の外へ伝える方法が必要。
// 同期処理と例外処理
function syncErrorFunc() {
  try {
    console.log("同期処理を開始します");

    console.log("処理1");
    console.log("処理2");
    
    throw new Error("同期処理中にエラーが発生しました");
  } catch(error) {
    console.log(error.message);
  }
}

syncErrorFunc();
// => 同期処理を開始します
// => 処理1
// => 処理2
// => 同期処理中にエラーが発生しました(キャッチできている)
// 非同期処理と例外処理
function asyncErrorFunc() {
  try {
    console.log("非同期処理を開始します");
  
    console.log("処理1");
    console.log("処理2");
  
    // 非同期処理を仮定
    setTimeout(() => {
        throw new Error("非同期処理中にエラーが発生しました");
    }, 1000);
  } catch (error) {
    // 非同期エラーはキャッチできないため、この行は実行されない
    console.log(error.message);
  }
}
asyncErrorFunc();
// => 非同期処理を開始します
// => 処理1
// => 処理2
// ...
// => Uncaught Error: 非同期的処理中にエラーが発生しました(キャッチできていない)

以降の関連記事②③④では主要な非同期処理および例外の扱い方として
② コールバックを用いた非同期処理
③ Promise
④ Async Function
について記載する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?