0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript】コールバック関数を理解しよう

0
Posted at

はじめに

JavaScriptでプログラミングをしていると、必ず出会うのがコールバック関数です。配列の操作や非同期処理など、さまざまな場面で使われる重要な概念ですが、最初は少し分かりにくいかもしれません。この記事では、コールバック関数の基本から実践的な使い方まで、順を追って解説していきます。

コールバック関数とは

コールバック関数とは、他の関数に引数として渡される関数のことです。渡された関数は、呼び出し元の関数の中で適切なタイミングで実行されます。

// 基本的な例
function greeting(name) {
  console.log(`こんにちは、${name}さん`);
}

function processUserInput(callback) {
  const name = "太郎";
  callback(name);  // ここでコールバック関数を実行
}

processUserInput(greeting);  // "こんにちは、太郎さん"

この例では、greeting関数がprocessUserInput関数にコールバック関数として渡されています。

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

匿名関数としてのコールバック

コールバック関数は、名前を付けずにその場で定義することもできます。

// 匿名関数を使用
processUserInput(function(name) {
  console.log(`こんにちは、${name}さん`);
});

// アロー関数を使用(ES6以降)
processUserInput((name) => {
  console.log(`こんにちは、${name}さん`);
});

配列メソッドでの利用

配列のmapfilterforEachなどのメソッドは、コールバック関数を活用する代表的な例です。

const numbers = [1, 2, 3, 4, 5];

// forEach:各要素に対して処理を実行
numbers.forEach((num) => {
  console.log(num * 2);
});

// map:各要素を変換して新しい配列を作成
const doubled = numbers.map((num) => num * 2);
console.log(doubled);  // [2, 4, 6, 8, 10]

// filter:条件に合う要素だけを抽出
const evenNumbers = numbers.filter((num) => num % 2 === 0);
console.log(evenNumbers);  // [2, 4]

非同期処理とコールバック

コールバック関数は、非同期処理において特に重要な役割を果たします。非同期処理とは、時間のかかる処理を待たずに次の処理を進める仕組みのことです。

タイマー処理

console.log("開始");

setTimeout(() => {
  console.log("2秒後に実行");
}, 2000);

console.log("終了");

// 出力順序:
// 開始
// 終了
// 2秒後に実行

イベント処理

// ボタンクリック時の処理
const button = document.getElementById("myButton");

button.addEventListener("click", () => {
  console.log("ボタンがクリックされました");
});

コールバック地獄とその対策

複数の非同期処理を順番に実行しようとすると、コールバック関数がネストして読みにくくなります。これを「コールバック地獄」と呼びます。

コールバック地獄の例

// 悪い例:ネストが深くなる
getData((data1) => {
  processData(data1, (data2) => {
    saveData(data2, (data3) => {
      notifyUser(data3, (result) => {
        console.log("完了");
      });
    });
  });
});

対策1: 名前付き関数を使う

// 改善例:関数を分割
function handleData1(data1) {
  processData(data1, handleData2);
}

function handleData2(data2) {
  saveData(data2, handleData3);
}

function handleData3(data3) {
  notifyUser(data3, handleResult);
}

function handleResult(result) {
  console.log("完了");
}

getData(handleData1);

対策2: PromiseやAsync/Awaitを使う

現代のJavaScriptでは、Promiseやasync/awaitを使うことで、より読みやすいコードを書けます。

// Promiseを使用
getData()
  .then(data1 => processData(data1))
  .then(data2 => saveData(data2))
  .then(data3 => notifyUser(data3))
  .then(result => console.log("完了"))
  .catch(error => console.error(error));

// async/awaitを使用
async function executeProcess() {
  try {
    const data1 = await getData();
    const data2 = await processData(data1);
    const data3 = await saveData(data2);
    const result = await notifyUser(data3);
    console.log("完了");
  } catch (error) {
    console.error(error);
  }
}

実践的な例:データ取得と表示

実際のアプリケーションでコールバック関数を使う例を見てみましょう。

// ユーザーデータを取得して表示する関数
function fetchUserData(userId, callback) {
  // 実際にはAPIからデータを取得
  setTimeout(() => {
    const userData = {
      id: userId,
      name: "山田太郎",
      email: "yamada@example.com"
    };
    callback(userData);
  }, 1000);
}

// 使用例
fetchUserData(123, (user) => {
  console.log(`ユーザー名: ${user.name}`);
  console.log(`メール: ${user.email}`);
});

まとめ

コールバック関数は、JavaScriptにおける重要な概念です。基本的な特徴を整理すると以下のようになります。

  • 他の関数に引数として渡される関数である
  • 配列メソッドや非同期処理で頻繁に使用される
  • ネストが深くなりすぎると可読性が低下する
  • 現代のJavaScriptでは、PromiseやAsync/Awaitを使うことで、より読みやすいコードを書ける

コールバック関数の仕組みを理解することで、JavaScriptのコードをより効果的に書けるようになります。最初は複雑に感じるかもしれませんが、実際に手を動かして練習することで、自然と使えるようになっていくでしょう。

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?