読み込み中...

TypeScriptでPromiseをマスターするたったの10の方法

TypeScriptとPromiseの連携イメージ TypeScript
この記事は約30分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

TypeScriptを利用した開発において、非同期処理は欠かせない要素となっています。

特にPromiseは、非同期処理を扱う上での中核を担っています。

本ガイドでは、TypeScriptでのPromiseの使い方や注意点、さらには応用例について、サンプルコードと共に徹底的に解説します。

初心者から上級者まで、Promiseの使い方を完全にマスターするためのステップを提供します。

●Promiseとは

Promiseは、JavaScriptやTypeScriptにおける非同期処理を表現するためのオブジェクトです。

非同期処理の結果を「約束」することから、この名前がつけられました。

主に、値が得られるか、あるいはエラーが生じるかのどちらかの結果を「約束」しています。

このコードでは、新しいPromiseオブジェクトを作成しています。

このPromiseオブジェクトは、非同期処理の結果を表すものです。

const promiseExample = new Promise((resolve, reject) => {
    // 非同期処理
    setTimeout(() => {
        resolve('成功!');
    }, 1000);
});

このコードを実行すると、1秒後に「成功!」という文字列を解決するPromiseが生成されます。

○TypeScriptとPromiseの関係性

TypeScriptはJavaScriptのスーパーセットであるため、JavaScriptの持つPromiseの機能はそのまま利用することができます。

しかし、TypeScriptには型安全性が追加されているため、Promiseの中で扱うデータの型を明示的に指定することができます。

下記のサンプルコードは、TypeScriptでのPromiseの型指定の例です。

const promiseTyped: Promise<string> = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('TypeScriptでのPromise');
    }, 1000);
});

このコードでは、Promiseが解決する値の型をstringとして指定しています。

このように、TypeScriptの型システムを活用することで、Promiseの中で扱うデータの型を明示的に管理できます。

○Promiseの3つの状態

Promiseには、次の3つの状態が存在します。

  1. pending (保留中):初期状態で、解決も拒否もされていない状態を指します。
  2. fulfilled (解決済み):非同期処理が正常に完了し、結果を持っている状態を指します。
  3. rejected (拒否済み):非同期処理で何らかのエラーが発生した状態を指します。

下記のサンプルコードでは、Promiseの3つの状態を表す例を見ることができます。

const promisePending = new Promise((resolve, reject) => {
    // 何もしないので、pendingのままです
});

const promiseFulfilled = Promise.resolve('解決済みのPromise');

const promiseRejected = Promise.reject(new Error('エラーが発生'));

このコードを実行すると、それぞれpendingの状態のPromise、解決済みのPromise、拒否済みのPromiseが生成されます。

●Promiseの基本的な使い方

JavaScript、そしてTypeScriptの非同期処理において、Promiseは中心的な役割を果たします。

非同期処理とは、時間のかかる処理(例:APIへのリクエストやデータベースへのクエリなど)をバックグラウンドで実行し、その処理が終了したときに結果を取得する仕組みのことを指します。

Promiseはこの非同期処理の結果を表現するためのオブジェクトであり、成功した場合や失敗した場合の処理をメソッドチェーンで書くことができます。

○サンプルコード1:Promiseを生成する基本的な方法

Promiseの作成は、new Promiseというコンストラクタを使用します。

このコンストラクタは、引数として実行関数を受け取ります。

実行関数は2つの引数、resolverejectを持ちます。

Promiseの基本的な生成方法のサンプルコードを紹介します。

const promise = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    // 3秒後に成功を表現
    resolve("成功!");
  }, 3000);
});

console.log("Promiseを開始します");

このコードでは、新しいPromiseオブジェクトを生成しています。

setTimeout関数を使って、3秒後にresolve関数を呼び出して、成功を表現しています。

resolve関数は、Promiseが正常に完了したときに呼び出す関数です。

このコードを実行すると、”Promiseを開始します”というメッセージがすぐに表示されます。

Promise自体の結果は3秒後に得られるので、その結果を表示するコードはこのサンプルには含まれていません。

適宜追加して下さい。

○サンプルコード2:then()を使用してPromiseが解決されたときの処理

Promiseは非同期処理の結果を表現するためのオブジェクトで、その結果を取得するためのメソッドがthen()です。

then()メソッドは、Promiseが正常に完了した(すなわち、解決された)場合に実行する処理を指定します。

この解決された値を受け取るためのコールバック関数を引数としてthen()に渡すことができます。

下記のサンプルコードでは、Promiseを作成し、その解決時にthen()を使って結果をコンソールに出力しています。

// Promiseの作成
const promiseExample = new Promise<string>((resolve, reject) => {
    setTimeout(() => {
        resolve("Promiseが正常に解決されました!");
    }, 2000); // 2秒後にPromiseを解決する
});

// then()を使用してPromiseが解決されたときの処理を記述
promiseExample.then((message) => {
    console.log(message);
});

このコードでは、setTimeoutを使って2秒後にPromiseを解決しています。

そして、then()メソッドを使って、その解決値をコンソールに出力しています。

このコードを実行すると、2秒後にコンソールに「Promiseが正常に解決されました!」というメッセージが表示されます。

○サンプルコード3:catch()を使用してPromiseが拒否されたときの処理

Promiseは、非同期処理の結果を表現するためのオブジェクトであり、成功した場合(fulfilled)と失敗した場合(rejected)の2つのメソッド、then()catch()を使用して、それぞれのケースでの処理を記述することができます。

今回は、Promiseが拒否されたとき、つまりエラーが発生した場合にどのように処理を行うかに焦点を当て、catch()メソッドの使用方法を解説します。

まず、基本的なサンプルコードを紹介します。

const promiseExample = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("何らかのエラーが発生しました。"));
    }, 1000);
});

promiseExample
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.error(`エラーが発生しました: ${error.message}`);
    });

このコードでは、setTimeoutを使って1秒後にPromiseが拒否されるように設定しています。

具体的には、reject()メソッドにErrorオブジェクトを渡して、エラーの原因を明確に表しています。

このPromiseが拒否されたとき、catch()メソッドが呼び出されます。

そのため、エラーメッセージがコンソールに出力されます。

このコードを実行すると、次のような結果が得られます。

エラーが発生しました: 何らかのエラーが発生しました。

重要なのは、catch()メソッドがPromiseが拒否されたときだけに呼び出される点です。

このメソッドを使用することで、非同期処理中のエラーを適切にハンドリングすることができます。

●Promiseとasync/await

JavaScriptの非同期処理の扱いは、時として複雑であり、多くの開発者が取り組み時に混乱を感じることがあります。

特にPromiseとasync/awaitの使い方や、それらの組み合わせ方について混乱することが多くなります。

しかし、TypeScriptの強力な型推論機能とともに、これらの非同期処理手法を適切に組み合わせることで、非常に効率的で読みやすいコードを書くことができます。

ここでは、Promiseとasync/awaitの基本的な使い方と、それらを組み合わせたときのメリットについて詳しく解説していきます。

○サンプルコード4:async/awaitを用いた非同期処理の簡潔な記述

sync/awaitを使用して非同期処理を行う簡潔な例を紹介します。

async function fetchData(): Promise<string> {
    let response = await fetch("https://api.example.com/data");
    let data = await response.json();
    return data.message;
}

このコードでは、fetch関数を使用して外部のAPIからデータを取得しています。

async/awaitを使用することで、非同期処理を同期処理のように直感的に記述することができます。

特に、awaitキーワードを使うことで、Promiseが解決されるのを待ってから次の行の処理に移ることができる点が大きな特徴です。

実際に上のコードを実行すると、外部のAPIから取得したデータのmessageプロパティの値を返す処理となります。

○サンプルコード5:try/catchを使用してasync/awaitでのエラーハンドリング

JavaScript及びTypeScriptでは、非同期処理にPromiseというオブジェクトを使用することが一般的です。

Promiseは非同期処理が完了するまでの「約束」を表現するオブジェクトで、非同期処理の結果を取得するための機能を提供します。

さらに、ES2017からは、async/awaitという構文が導入され、非同期処理の記述がより直感的で読みやすくなりました。

しかし、非同期処理はエラーが発生しやすいものです。

そのため、エラーハンドリングの方法を知っておくことは非常に重要です。

特にasync/awaitを使用する場合、通常のtry/catch文を使ってエラーハンドリングを行うことができます。

次に、async/awaitを使用した非同期処理中にエラーが発生した場合のエラーハンドリング方法を具体的なサンプルコードとともに説明します。

// 非同期の関数を定義
async function fetchData(url: string): Promise<string> {
    if(url === 'error') {
        throw new Error('データの取得に失敗しました。');
    }
    return 'データ';
}

// async/awaitを使用して非同期処理を行う関数を定義
async function main() {
    try {
        const data = await fetchData('error');  // エラーを発生させるため、引数に'error'を渡す
        console.log(data);
    } catch (error) {
        console.error('エラーが発生しました:', error.message);
    }
}

main();

このコードでは、fetchDataという非同期関数を定義しています。

引数として’url’を受け取り、その’url’が’error’の場合、エラーをスローします。

この非同期関数を実行するmain関数内で、try/catchを使用してエラーハンドリングを行っています。

このコードを実行すると、fetchData関数内でエラーが発生し、catchブロックが実行されます。

そのため、”エラーが発生しました:”というメッセージがコンソールに表示されるとともに、エラーメッセージも出力されます。

●Promise.allとPromise.raceの利用方法

JavaScriptとそのスーパーセットであるTypeScriptでは、非同期処理を効果的に行うための方法としてPromiseを用いることが一般的です。

特に、複数の非同期処理を並列で行う場合や、最初に完了する非同期処理を取得する際にPromise.allPromise.raceといった便利なメソッドが提供されています。

ここでは、これらのメソッドを使用してTypeScriptでの非同期処理の取り扱い方について詳しく解説します。

○サンプルコード6:Promise.allを使用して複数のPromiseを並列に実行

複数の非同期処理を並列に実行し、全ての処理が完了した際の結果を取得する場合、Promise.allを使用します。

これは、指定された全てのPromiseが解決されると、それらの結果の配列を返すメソッドです。

Promise.allを使用して3つの非同期処理を並列に実行するサンプルコードを紹介します。

const promise1 = new Promise<string>((resolve) => {
    setTimeout(() => {
        resolve("結果1");
    }, 1000);
});

const promise2 = new Promise<string>((resolve) => {
    setTimeout(() => {
        resolve("結果2");
    }, 1500);
});

const promise3 = new Promise<string>((resolve) => {
    setTimeout(() => {
        resolve("結果3");
    }, 500);
});

Promise.all([promise1, promise2, promise3]).then((results) => {
    console.log(results); // ["結果1", "結果2", "結果3"]
});

このコードでは、3つのPromiseを生成しており、それぞれ異なる時間後に解決されるようにしています。

Promise.allメソッドを使用すると、これらのPromiseの全てが解決されたときに、その結果の配列を取得することができます。

したがって、上記のコードを実行すると、約1.5秒後に["結果1", "結果2", "結果3"]という結果がコンソールに表示されます。

このメソッドを利用することで、複数の非同期処理を並行して行い、その結果を効率的に収集することができます。

特に、API通信やデータベースへの問い合わせなど、複数の操作を同時に行いたい際に有効です。

○サンプルコード7:Promise.raceを使用して複数のPromiseの中で最初に完了するものを取得

Promiseには様々な利用方法がありますが、Promise.raceはその中でも非常に便利なメソッドの一つです。

このメソッドを使うと、複数のPromiseオブジェクトから最初に完了するものを取得することができます。

このコードでは、Promise.raceを使って、3つの異なるPromiseオブジェクトの中から最初に完了するものを取得します。

具体的には、それぞれ1秒、2秒、3秒後に完了するPromiseを用意し、どれが最初に完了するかを確認します。

const promise1 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    resolve('1秒後のPromise');
  }, 1000);
});

const promise2 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    resolve('2秒後のPromise');
  }, 2000);
});

const promise3 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    resolve('3秒後のPromise');
  }, 3000);
});

Promise.race([promise1, promise2, promise3]).then((message) => {
  console.log(message);
});

このコードを実行すると、1秒後に「1秒後のPromise」というメッセージがコンソールに表示されます。

これは、3つのPromiseオブジェクトの中でpromise1が最も早く完了するためです。

Promise.raceは、どれか一つのPromiseが完了するとすぐに次の処理に進みます。

そのため、最も早く完了するPromiseの結果しか取得できません。

この特性を活かして、タイムアウト処理などの実装にも利用されることがあります。

例えば、あるAPIの応答を最大5秒待ちたい場合、5秒後に拒否されるPromiseとAPIの応答を待つPromiseをPromise.raceで競わせることで、5秒経ってもAPIからの応答がなければタイムアウトとして処理を進める、といったことが可能です。

それでは、上記の例にタイムアウトを追加してみましょう。

const apiCall = new Promise<string>((resolve, reject) => {
  // 仮に3秒後にAPIの応答が返ってきたとします
  setTimeout(() => {
    resolve('APIの応答');
  }, 3000);
});

const timeout = new Promise<string>((_, reject) => {
  setTimeout(() => {
    reject('5秒経ったのでタイムアウト');
  }, 5000);
});

Promise.race([apiCall, timeout]).then((message) => {
  console.log(message);
}).catch((error) => {
  console.error(error);
});

このコードを実行すると、3秒後に「APIの応答」というメッセージがコンソールに表示されます。

しかし、APIの応答が5秒以上かかる場合は、「5秒経ったのでタイムアウト」というエラーメッセージがコンソールに表示されます。

●Promiseの応用例

JavaScriptの非同期処理としてPromiseは非常に便利ですが、TypeScriptを使用することでさらに強力で堅牢な非同期処理を実現することができます。

ここでは、TypeScriptを使用したPromiseの応用例を解説します。

○サンプルコード8:非同期処理を順番に実行する方法

非同期処理を行う際、ある非同期処理が完了した後に次の非同期処理を行うというシーケンスが必要になることがあります。

このような場面では、Promiseチェーンを活用して非同期処理を順番に実行することができます。

TypeScriptを使った非同期処理を順番に実行するサンプルコードを紹介します。

// 非同期関数の定義
const firstAsyncFunction = (): Promise<string> => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('First Function Finished');
    }, 1000);
  });
};

const secondAsyncFunction = (): Promise<string> => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Second Function Finished');
    }, 2000);
  });
};

// 非同期処理を順番に実行
firstAsyncFunction().then(result1 => {
  console.log(result1);  // First Function Finished
  return secondAsyncFunction();
}).then(result2 => {
  console.log(result2);  // Second Function Finished
});

このコードでは、firstAsyncFunctionsecondAsyncFunctionという2つの非同期関数を定義しています。

各関数は指定された時間が経過した後に、メッセージを解決するPromiseを返します。

非同期処理を順番に実行するために、thenメソッドを使って、firstAsyncFunctionが完了した後にsecondAsyncFunctionを呼び出しています。

このコードを実行すると、まず”First Function Finished”が出力され、その後に”Second Function Finished”が出力されます。

このようにPromiseチェーンを使用すると、複数の非同期処理を順番に実行することが容易になります。

○サンプルコード9:APIの非同期通信でのデータ取得

TypeScriptとPromiseを使用して、APIから非同期通信によってデータを取得する方法を見ていきます。

下記のサンプルコードは、HTTPリクエストを使って外部APIからデータを取得するシンプルな例です。

// 必要なモジュールのインポート
import axios from 'axios';

// APIからデータを非同期で取得する関数
async function fetchData(url: string): Promise<any> {
    try {
        // axiosを使用してGETリクエストを実行
        const response = await axios.get(url);
        return response.data;
    } catch (error) {
        throw new Error(`APIからのデータ取得に失敗しました: ${error.message}`);
    }
}

// 使用例
const API_URL = 'https://api.example.com/data';

fetchData(API_URL)
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error(error.message);
    });

このコードでは、まずaxiosというライブラリを使用して非同期通信を行っています。

axiosは非常にポピュラーなHTTPクライアントで、PromiseベースのAPIを提供しているため、非常に扱いやすいです。

関数fetchDataは、引数としてAPIのURLを受け取り、そのURLに対してGETリクエストを行います。

この関数はasync関数として定義されているため、内部でawaitキーワードを使用することができます。

awaitは、Promiseが解決されるのを待つキーワードです。

そのため、axios.get(url)の処理が完了するまで、次の行には進みません。

APIからのレスポンスを取得した後、response.dataでそのデータを返しています。

もしAPIリクエスト中に何らかのエラーが発生した場合は、try-catch文によってそのエラーを捕捉し、適切なエラーメッセージとともにErrorをスローします。

このコードを実行すると、指定したAPI_URLからデータを非同期に取得し、そのデータをコンソールに表示します。

もしAPIからのデータ取得中にエラーが発生した場合、エラーメッセージがコンソールに表示されます。

○サンプルコード10:Promiseを使った簡易的なタスクキューの実装

JavaScriptおよびTypeScriptの非同期処理において、複数のタスクを順番に実行することがしばしば要求されます。

ここでは、Promiseを使用して簡易的なタスクキューを実装する方法を取り上げます。

この実装により、タスクが順番に、そして一つずつ実行されることが保証されます。

このコードでは、タスクキューを管理するクラスTaskQueueを作成しています。

このクラスの主要な機能は、タスクをキューに追加し、それを順番に実行することです。

class TaskQueue {
    private queue: Array<() => Promise<any>> = [];
    private isRunning = false;

    // タスクをキューに追加するメソッド
    public enqueue(task: () => Promise<any>) {
        this.queue.push(task);
        this.run();
    }

    private async run() {
        if (this.isRunning || this.queue.length === 0) return;
        this.isRunning = true;
        const task = this.queue.shift();
        if (task) {
            await task();
        }
        this.isRunning = false;
        this.run();
    }
}

このコードでは、TaskQueueクラスには主に2つのメソッドが定義されています。

一つ目はenqueueで、非同期タスクをキューに追加するためのメソッドです。

二つ目はrunで、キューのタスクを順番に実行するためのメソッドです。

こちらは外部から呼び出すことはなく、enqueueメソッドからのみ呼び出される内部的なメソッドです。

このコードを実行すると、タスクはenqueueメソッドを通してキューに追加され、その後runメソッドによって順番に実行されます。

これにより、複数の非同期タスクを簡単にキューイングし、順番に実行することができます。

例として、上記のTaskQueueクラスを使って、3つの非同期タスクをキューイングし、順番に実行する例を見てみましょう。

const taskQueue = new TaskQueue();

const task1 = () => {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log('Task 1 finished!');
            resolve(null);
        }, 1000);
    });
};

const task2 = () => {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log('Task 2 finished!');
            resolve(null);
        }, 2000);
    });
};

const task3 = () => {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log('Task 3 finished!');
            resolve(null);
        }, 500);
    });
};

taskQueue.enqueue(task1);
taskQueue.enqueue(task2);
taskQueue.enqueue(task3);

このコード例では、3つの非同期タスクtask1, task2, task3がそれぞれ1秒、2秒、500ミリ秒後に完了するように設定されています。

これらのタスクをTaskQueueに追加すると、Task 1 finished!Task 2 finished!Task 3 finished!の順番でコンソールにログが表示されることが期待されます。

●Promiseの注意点と対処法

Promiseは非同期処理を扱いやすくする素晴らしいツールですが、正しく使用しないと、多くの問題点が浮上してきます。

ここでは、TypeScriptを使用してPromiseを効果的に使用するための注意点とその対処法について詳しく解説します。

○メモリリークに関する注意点

Promiseの使用においてメモリリークはしばしば見逃される問題点の一つです。

特に、未解決のPromiseを大量に作成し、それらを適切に解放しない場合、アプリケーションのパフォーマンスが低下する原因となります。

このコードでは、未解決のPromiseを大量に生成しています。

for (let i = 0; i < 1000000; i++) {
    new Promise((resolve, reject) => {
        // 解決されないPromise
    });
}

このコードを実行すると、未解決のPromiseが1000000回生成されるため、メモリ消費が増加します。

対処法として、未解決のPromiseを適切に管理し、不要になったら解放することが重要です。

たとえば、setTimeout関数を使用して、一定時間後にPromiseを解決または拒否することで、メモリリークのリスクを軽減できます。

for (let i = 0; i < 1000000; i++) {
    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('完了');
        }, 1000 * i);
    });
}

この修正されたコードでは、各Promiseはi秒後に解決されるため、メモリリークのリスクが低減します。

○エラーハンドリングのベストプラクティス

Promiseのもう一つの重要な注意点は、エラーハンドリングです。

適切なエラーハンドリングを行わないと、予期しないエラーが発生した場合、それをキャッチせずにアプリケーションがクラッシュするリスクがあります。

エラーを適切にハンドリングしていないコードの例を紹介します。

function fetchData() {
    return new Promise((resolve, reject) => {
        // データ取得の処理
        // 何らかの理由でエラーが発生
        reject('データ取得エラー');
    });
}

fetchData().then(data => {
    console.log(data);
});

このコードを実行すると、Promiseが拒否されると、エラーはキャッチされずにプログラムがクラッシュします。

対処法として、エラーハンドリングを実施するために、catchメソッドを使用して、Promiseが拒否された場合の処理を記述します。

fetchData()
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error('エラーが発生しました:', error);
    });

この修正されたコードでは、Promiseが拒否された場合でもエラーがキャッチされ、適切なエラーメッセージがコンソールに出力されます。

●Promiseのカスタマイズ方法

Promiseは非常に強力で、多くの非同期操作を簡単に実現できますが、デフォルトの挙動だけでは不足する場面もあります。

特定の要件やプロジェクトのニーズに合わせて、Promiseをカスタマイズすることでさらに高度な制御やエラーハンドリングが可能となります。

○カスタムエラーハンドラの実装

JavaScriptのPromiseには、エラーが発生した際にそれを処理するためのcatch()メソッドが存在します。

しかし、TypeScriptでの強力な型システムを利用して、カスタムエラーハンドラを実装することができます。

特定のエラータイプごとに異なる処理を行いたい場合や、エラー情報を詳細にログするなど、高度なエラーハンドリングが求められる場合に役立ちます。

このコードでは、独自のエラー型を定義し、それに基づいてエラーハンドリングを行います。

// カスタムエラータイプの定義
class NotFoundError extends Error {
    constructor(message: string) {
        super(message);
        this.name = "NotFoundError";
    }
}

class NetworkError extends Error {
    constructor(message: string) {
        super(message);
        this.name = "NetworkError";
    }
}

const fetchData = (): Promise<string> => {
    return new Promise((resolve, reject) => {
        // ここではデモのためエラーを強制的に発生させます
        reject(new NetworkError("ネットワーク接続エラー"));
    });
};

fetchData().catch(error => {
    if (error instanceof NetworkError) {
        console.log("ネットワーク関連のエラーが発生しました。");
    } else if (error instanceof NotFoundError) {
        console.log("要求されたリソースが見つかりませんでした。");
    } else {
        console.log("未知のエラーが発生しました。");
    }
});

このコードを実行すると、”ネットワーク関連のエラーが発生しました。”というメッセージが表示されます。

カスタムエラークラスを使用して、エラーの種類ごとに異なる処理を実施しています。

○Promiseチェーンの拡張

Promiseはチェーン可能であり、複数の非同期操作を順番に実行したり、同時に実行したりすることができます。

しかし、特定の条件下でのみ次の処理を実行する、といったようなカスタムのロジックを追加することも考えられます。

下記の例では、Promiseの結果に基づいて次の処理を実行するかどうかを判断するカスタムのPromiseチェーンを作成します。

const fetchDataConditionally = (condition: boolean): Promise<string> => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (condition) {
                resolve("データ取得成功");
            } else {
                reject("データ取得失敗");
            }
        }, 1000);
    });
};

fetchDataConditionally(true)
    .then(data => {
        console.log(data); // データ取得成功
        return fetchDataConditionally(false);
    })
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.log(error); // データ取得失敗
    });

このコードを実行すると、”データ取得成功”と表示された後、”データ取得失敗”と表示されます。

条件に基づいて次のPromiseを実行するかどうかを制御しています。

まとめ

TypeScriptにおけるPromiseの使い方を完全に理解することは、効果的な非同期プログラミングのための鍵となります。

この記事で、私たちはPromiseとその使用方法、そしてTypeScriptにおけるその関連性について徹底的に探求しました。

Promiseは非同期処理の結果を表現するための強力なツールであり、TypeScriptはそれをより型安全に、そして読みやすくすることができます。

非同期プログラミングは、特にWeb開発において避けて通れないテーマです。

TypeScriptを活用することで、Promiseをより安全かつ効率的に使用することができます。

このガイドが、あなたのTypeScriptプロジェクトでのPromiseの活用をサポートする手助けとなることを願っています。