JavaScript

JavaScriptの非同期処理について解説

JavaScriptの非同期処理は、時間のかかるタスク(ネットワークリクエスト、ファイルの読み書き、タイマーなど)をブロックせずに実行するための方法です。非同期処理を使用すると、ユーザーインターフェースをスムーズに保ちながら、他のタスクを並行して実行できます。

非同期処理の主な方法

  1. コールバック(Callbacks)
  2. プロミス(Promises)
  3. async/await構文

1. コールバック(Callbacks)

コールバックは、非同期タスクが完了したときに呼び出される関数です。コールバックは関数の引数として渡され、タスクが完了したときに実行されます。

基本的な構文

function asyncTask(callback) {
    setTimeout(() => {
        callback("タスク完了");
    }, 1000);
}

asyncTask((message) => {
    console.log(message);  // 1秒後に "タスク完了" が表示される
});

コールバック地獄(Callback Hell)

複数の非同期タスクを順番に実行する場合、コールバックのネストが深くなることがあります。これを「コールバック地獄」と呼びます。

function task1(callback) {
    setTimeout(() => {
        console.log("タスク1完了");
        callback();
    }, 1000);
}

function task2(callback) {
    setTimeout(() => {
        console.log("タスク2完了");
        callback();
    }, 1000);
}

function task3(callback) {
    setTimeout(() => {
        console.log("タスク3完了");
        callback();
    }, 1000);
}

task1(() => {
    task2(() => {
        task3(() => {
            console.log("すべてのタスク完了");
        });
    });
});

2. プロミス(Promises)

プロミスは、非同期操作の最終的な完了(または失敗)を表すオブジェクトです。プロミスは、thencatchfinallyメソッドを使用して、非同期タスクの結果を処理します。

基本的な構文

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("タスク完了");
    }, 1000);
});

promise.then((message) => {
    console.log(message);  // 1秒後に "タスク完了" が表示される
}).catch((error) => {
    console.error(error);
});

プロミスチェーン

プロミスチェーンを使用すると、複数の非同期タスクを順番に実行できます。

function task1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("タスク1完了");
            resolve();
        }, 1000);
    });
}

function task2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("タスク2完了");
            resolve();
        }, 1000);
    });
}

function task3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("タスク3完了");
            resolve();
        }, 1000);
    });
}

task1()
    .then(task2)
    .then(task3)
    .then(() => {
        console.log("すべてのタスク完了");
    })
    .catch((error) => {
        console.error(error);
    });

3. async/await構文

async/awaitは、プロミスをよりシンプルに扱うための構文糖です。async関数はプロミスを返し、awaitはプロミスが解決されるまで待機します。

基本的な構文

async function asyncTask() {
    let result = await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("タスク完了");
        }, 1000);
    });

    console.log(result);  // 1秒後に "タスク完了" が表示される
}

asyncTask();

非同期タスクの順序実行

async/awaitを使用すると、非同期タスクを同期的なコードのように記述できます。

function task1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("タスク1完了");
            resolve();
        }, 1000);
    });
}

function task2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("タスク2完了");
            resolve();
        }, 1000);
    });
}

function task3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("タスク3完了");
            resolve();
        }, 1000);
    });
}

async function runTasks() {
    try {
        await task1();
        await task2();
        await task3();
        console.log("すべてのタスク完了");
    } catch (error) {
        console.error(error);
    }
}

runTasks();

非同期処理の選択基準

  • コールバック: 単純な非同期処理には便利ですが、複雑な処理ではコールバック地獄に陥りやすいです。
  • プロミス: コールバック地獄を避け、非同期タスクのチェーンを簡単に管理できます。
  • async/await: 非同期処理を同期的なコードのように書くことができ、可読性が高まります。

まとめ

  • コールバック: 関数の引数として渡され、非同期タスクの完了後に実行される関数。
  • プロミス: 非同期操作の最終的な完了(または失敗)を表すオブジェクト。thencatchfinallyメソッドで結果を処理。
  • async/await構文: プロミスを扱うための構文糖。非同期タスクを同期的なコードのように記述できる。

これでJavaScriptの非同期処理についての基本的な理解が深まったと思います。

スポンサーリンク

-JavaScript