TypeScript コールバック

コールバックとは、他の関数に引数として渡され、呼び出した関数によって後で実行される関数のことです。コールバックは、ネットワークへのリクエストやファイルからの読み込みといった非同期処理を行う際によく利用されます。

それでは、TypeScriptのシンプルなコールバック関数の例を見てみましょう。

function add(a: number, b: number, callback: (result: number) => void): void {
    const result = a + b;
    callback(result);
}

add(1, 2, (result) => {
    console.log(result); // 3
});

この例では、add関数は3つの引数を取ります。2つの数値(a, b)とコールバック関数(callback)です。コールバック関数は(result: number) => void型で、数値型の引数を1つだけ取り、何も返しません。add関数はコールバック関数を使用して、加算結果を呼び出し元のコードに返します。

この例では、add関数のコールバックとして無名関数を渡しています。無名関数は引数を一つ取り(result)、コンソールにログを出力します。add関数が呼ばれると、コールバック関数が実行され、引数として加算結果(3)が渡されます。

それでは、他の例を見てみましょう。

function processData(data: string[], callback: (result: string) => void): void {
    let result = "";
    for (const item of data) {
        result += item.toUpperCase() + " ";
    }
    result = result.trimEnd();
    callback(result);
}

processData(["hello", "world"], (result) => {
    console.log(result); // "HELLO WORLD"
});

この例では、関数processDataは、文字列の配列(data)とコールバック関数(callback)を引数として受け取ります。コールバック関数は (result: string) => void型で、string型の引数を1つだけ取り、何も返しません。

processData関数は、データ配列を繰り返し処理し、各文字列を大文字に連結して1つの結果文字列を生成します。そして、コールバック関数を使用して、呼び出し元のコードに結果の文字列を返します。

この例では、processData関数のコールバックとして無名関数を渡しています。この無名関数は、1つの引数(result)を受け取り、コンソールにログを出力します。

では、setTimeoutを使ったコールバック関数の使用例を見てみましょう。

function delayedGreeting(name: string, callback: (greeting: string) => void): void {
    setTimeout(() => {
        const greeting = `Hello, ${name}!`;
        callback(greeting);
    }, 1000);
}

delayedGreeting("John", (greeting) => {a
    console.log(greeting); // "Hello, John!"
});

この例では、関数delayedGreetingは、文字列の引数(name)とコールバック関数(callback)を引数として受け取ります。コールバック関数は、(greeting: string) => void型で、string型の引数を一つ取り、何も返しません。

関数delayedGreetingは、setTimeoutを使って1秒後にコールバックを実行し、挨拶文を作成してコールバック関数の引数として渡しています。

関数delayedGreetingへのコールバックとして、無名関数を渡しています。この無名関数は一つの引数(greeting)を受け取り、コンソールにログを出力します。

この関数はsetTimeoutが終了した後にコールバックを使用してメッセージを出力しています。これはデータの読み込みやアニメーション、ユーザーとのインタラクションなど、遅延が発生する可能性のある実世界のシナリオを扱う場合によくあるパターンです。

では、少し複雑な例を見てみましょう。

function getUserData(userId: number, callback: (user: { name: string; age: number }) => void): void {
    const users = [{ id: 1, name: "John", age: 30 }, { id: 2, name: "Jessica", age: 25 }];
    const user = users.find((u) => u.id === userId);
    callback(user);
}

let user;
getUserData(1, (data) => {
    user = data;
});

console.log(user); // { id: 1, name: "John", age: 30 }

この例では、getUserData関数は、ユーザーID(userId)とコールバック関数(callback)を引数として受け取ります。コールバック関数は、(user: { name: string; age: number }) => void型で、{ name: string; age: number }型の引数を1つだけ取り、何も返しません。

getUserData関数は、引数userIdと同じIDを持つユーザーをusers配列から見つけ、コールバック関数を使用してユーザーデータを呼び出し元のコードに返します。

また、コールバックを使ってUIを更新することもできるでしょう。例えば、ユーザー情報を取得するリクエストを行っていて、アプリに名前や年齢を表示したいとすると、データが返ってきた後にコールバックでUI変更を実行することができます。

getUserData(1, (data) => {
    const nameLabel = document.getElementById("name");
    const ageLabel = document.getElementById("age");
    nameLabel.innerText = data.name;
    ageLabel.innerText = data.age;
});

この場合、コールバックはデータが返された後にUIを更新するために使用されています。

このように、コールバックは非同期処理の処理方法について多くの柔軟性を提供し、コールバックを持つ関数から返されたデータを簡単に操作して使用することができます。

Note: コールバックについては、CS基礎/上級/ラムダ関数で詳しく学習できます。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート