ブロッキングとノンブロッキング | 非同期処理とは? | JavaScript 超完全入門 基本から発展までのすべて

スポンサーリンク
スポンサーリンク

ブロッキングとノンブロッキングとは?

ブロッキングとノンブロッキングは、コンピュータプログラミングにおける処理の進行方法を指す重要な概念です。ブロッキングとは、ある処理が完了するまで次の処理が停止することを意味し、一方、ノンブロッキングでは、ある処理が完了するのを待たずに次の処理が進行します。

ブロッキングの仕組み

ブロッキング処理では、ある操作が終わるまでプログラムの実行が停止します。たとえば、ファイルの読み込みやネットワーク通信が完了するまで、次の命令は実行されません。これにより、シンプルで理解しやすいコードが書けますが、長時間かかる処理が発生すると、アプリケーション全体が待機状態となってしまうリスクがあります。

ブロッキング処理の例

function readFileSync() {
    // この関数がファイルを読み込むとき、処理は完了するまで停止する
    const data = fs.readFileSync("/path/to/file.txt", "utf8");
    console.log(data);
}

readFileSync(); // ファイルが読み込まれるまで次の処理は実行されない
console.log("ファイル読み込み後に実行される処理");

この例では、readFileSync関数がファイルの読み込みを完了するまで、次のconsole.logは実行されません。

ノンブロッキングの仕組み

一方、ノンブロッキング処理では、長時間かかる処理が完了するのを待たずに次の命令が実行されます。JavaScriptでは、非同期処理を使ってノンブロッキングを実現します。これにより、時間のかかる操作を待つ間も、他の処理を並行して進めることができ、アプリケーションの応答性が向上します。

ノンブロッキング処理の例

function readFileAsync() {
    // 非同期でファイルを読み込み、処理を続行する
    fs.readFile("/path/to/file.txt", "utf8", function(err, data) {
        if (err) {
            console.error(err);
            return;
        }
        console.log(data);
    });
}

readFileAsync(); // ファイルが読み込まれている間も次の処理が進む
console.log("ファイル読み込み中でも実行される処理");

この例では、readFileAsyncが非同期でファイルを読み込むため、ファイルが読み込まれる間にもconsole.logが実行され、他の操作がブロックされることなく進行します。

ブロッキングとノンブロッキングの比較

以下の表は、ブロッキング処理とノンブロッキング処理の違いを整理したものです。

処理の種類 特徴
ブロッキング処理 1つの操作が完了するまで、他の処理は停止する。シンプルだが、重い処理があると全体のパフォーマンスに影響が出る。
ノンブロッキング処理 操作の完了を待たずに次の処理が進行する。より効率的だが、非同期処理を理解しなければいけない。

ノンブロッキング処理の利点

ノンブロッキング処理には以下のような利点があります。

  • アプリケーションの応答性が向上する:ファイル読み込みやサーバーからのデータ取得などの重い処理を待つ間にも、他の操作が進行できる。
  • パフォーマンスの向上:複数の非同期処理を並行して実行することで、システム全体のパフォーマンスが向上する。
  • ユーザーエクスペリエンスの向上:ノンブロッキング処理を使用することで、ユーザーの操作に対してインタラクティブでスムーズな応答が可能になる。

ブロッキングが問題となるケース

ブロッキング処理が問題になる典型的なケースには、ファイルの読み込みや外部サーバーとの通信が含まれます。これらの操作が完了するまで、JavaScriptの実行が停止するため、ユーザーの操作に対する応答が遅れ、アプリケーションが「フリーズ」しているように見えることがあります。

ブロッキング処理によるフリーズの例

function waitForLongTask() {
    const start = Date.now();
    while (Date.now() - start < 5000) {
        // 5秒間待機する
    }
    console.log("長時間の処理が完了しました");
}

waitForLongTask(); // この間、ブラウザの操作がブロックされる
console.log("次の処理が実行される");

この例では、5秒間処理を停止するため、その間に他の操作は実行されません。ユーザーにとっては、アプリケーションがフリーズしているように感じられます。

ノンブロッキング処理の実装

ノンブロッキング処理を正しく実装するためには、コールバック関数、Promise、そしてasync/awaitといった非同期処理の仕組みを理解することが重要です。これらの技術を使うことで、非同期処理を簡潔かつ効率的に管理することができます。

async/awaitを使ったノンブロッキング処理の例

async function fetchData() {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    console.log(data);
}

fetchData(); // データの取得を待っている間に他の処理が進行する
console.log("データ取得中にも他の処理が進む");

この例では、async/awaitを使って非同期処理を簡潔に記述しています。データ取得中にも次の処理が進行するため、アプリケーション全体のパフォーマンスが向上します。

まとめ

ブロッキングとノンブロッキングは、JavaScriptの実行フローにおける重要な概念です。ブロッキング処理では、時間のかかる操作がアプリケーション全体のパフォーマンスに影響を与えますが、ノンブロッキング処理を使うことで、効率的な実行フローを保ちながら、ユーザーにスムーズな体験を提供できます。非同期処理の基本を理解し、適切に使い分けることが、パフォーマンス向上の鍵となります。