コールバック関数について調べてみる

2025年3月2日

chatGPTを使ってコールバック関数について調べてみました。

現在のレベル

「コールバック関数って、関数内で呼び出される関数のことでしょ?」

「なんかPromiseの登場によって使わてもよくなったやつ?」


(質問)コールバック関数について、初学者でも分かるように説明してください。

コールバック関数(callback function)とは、ある処理が終わった後に
「次に実行するために呼ばれる関数」のことです。
簡単に言うと、「関数の中に渡す、後で実行される関数」 です。

■コールバック関数を使う理由

通常、プログラムは上から下に順番に実行されますが、コールバック関数は、
例えば非同期処理(時間がかかる処理)をした後に別の処理を行いたい場合に使います。

例えば:

・サーバーからデータを取得した後に、取得したデータを使って別の処理をしたい。
・ユーザーがボタンをクリックした後に、特定のアクションを実行したい。

■コールバック関数の基本的な使い方

コールバック関数は、他の関数に引数として渡して、実行が完了したタイミングで呼ばれます。
function greet(name, callback) {
  console.log("Hello, " + name);
  callback();  // コールバック関数を呼び出す
}

function sayGoodbye() {
  console.log("Goodbye!");
}

greet("Alice", sayGoodbye);  // 「Hello, Alice」が表示された後、「Goodbye!」が表示される

つまり、関数の中で呼び出される関数というだけではなく、実行されるタイミング(非同期処理)をコントロールできることが重要という訳ですね。


(質問)Promiseとの関係について教えてください。

■コールバック関数とPromiseの違い

コールバック関数: 
非同期処理が完了した後に実行される関数を指定します。
非同期処理が複雑になると、コールバック関数が入れ子(ネスト)になって、
コードが見づらくなることがあります(これを「コールバック地獄」と呼びます)。
Promise: 
非同期処理を扱うためのオブジェクトで、処理が成功した場合や失敗した場合に
どのように結果を扱うかを指定します。
Promiseは、非同期処理が完了する前に値を返さない代わりに、
後で結果が返ってくることを約束(Promise)するものです。

■Promiseを使った例

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = "データ取得成功!";
      resolve(data);  // データ取得成功した場合
    }, 1000);
  });
}

fetchData()
  .then(result => {
    console.log(result);  // データ取得成功!
    return "次の処理";
  })
  .then(nextResult => {
    console.log(nextResult);  // 次の処理
  })
  .catch(error => {
    console.error("エラー:", error);  // エラー処理
  });

■Promiseを使うメリット

  • 非同期処理のチェーン: .then() を使って、非同期処理の結果を順番に処理することができます。
  • エラーハンドリング: .catch() でエラーを一元的に処理できます。
  • 可読性の向上: 非同期処理の順番が明確になり、コードが読みやすくなります。

(質問)Promiseでなく、コールバック関数を使わざるを得ない場合はありますか?

解答はいくつかあったのですが、下記が重要と感じました。

■イベントリスナー(リアルタイム処理)の場合

Promiseは一度しか解決(resolve/reject)できないため、
繰り返し発生するイベントには向いていません。
イベントリスナーを使う場合は、コールバック関数が必要になります。
document.addEventListener("click", () => {
  console.log("クリックされました!");
});

なぜPromiseを使えない?

Promise は 一度しか実行されない ため、複数回のクリックを処理できません。
イベントが発生するたびに実行される処理は、コールバック関数が最適です。

■JavaScriptの一部の非同期処理(例えば、setTimeout)

setTimeout や setInterval などの組み込み関数は、コールバック関数しか受け付けません。
setTimeout(() => {
  console.log("3秒後に実行されました!");
}, 3000);

まとめ

今回はコールバック関数について調べました。

とりあえずPromiseを使っていればいいやと思っていましたが、コールバック関数が必要になるケースについても知ることができました。

次はasync/awaitとの関係についても学習したいと思いますが、長くなりそうなので一旦区切りたいと思います。


記事一覧に戻る