TypeScriptにおけるPromiseクラス

TypeScriptにおけるPromiseクラス

この記事ではTypeScriptにおけるPromiseクラスについて説明します。

YouTube Video

Promise

TypeScriptにおけるPromiseクラスは、JavaScriptのPromiseと基本的に同じです。Promiseは非同期処理を扱うためのビルトインクラスであり、非同期操作が完了した時の結果を表現するオブジェクトです。ここでは、Promiseの基本的な使い方と関連コンセプトについて説明します。

基本的な使い方

Promiseの作成:

Promiseオブジェクトは、非同期処理をラップするために使用されます。Promisenew Promise(executor)として作成され、その中で非同期処理を実行します。executorresolverejectの2つの関数を引数として受け取ります。

1const myPromise = new Promise<number>((resolve, reject) => {
2    // Perform asynchronous operations
3    const success = true; // This is just an example
4    if (success) {
5        resolve(42); // In case of success
6    } else {
7        reject('Failed'); // In case of failure
8    }
9});

Promiseの利用:

生成したPromiseは、then()catch()を使って結果を処理します。

1myPromise.then((value) => {
2    console.log(`Success: ${value}`); // Process the value passed with resolve
3}).catch((error) => {
4    console.error(`Error: ${error}`); // Handle the error passed with reject
5});

finally()メソッド

 1const myPromise = new Promise<number>((resolve, reject) => {
 2    // Perform asynchronous operations
 3    const success = false; // This is just an example
 4    if (success) {
 5        resolve(42); // In case of success
 6    } else {
 7        reject('Failed'); // In case of failure
 8    }
 9});
10
11myPromise.then((value) => {
12    console.log(`Success: ${value}`); // Process the value passed with resolve
13}).catch((error) => {
14    console.error(`Error: ${error}`); // Handle the error passed with reject
15}).finally(() => {
16    console.log('The operation has completed');
17});
  • finally()メソッドは、Promiseが成功または失敗のいずれにしても、最終的に必ず実行されるコードを定義します。

Promiseのチェーン:

then()に続けてthen()を繋げることで、複数の非同期操作を連鎖させることができます。

 1const myPromise = new Promise<number>((resolve, reject) => {
 2    // Perform asynchronous operations
 3    const success = true; // This is just an example
 4    if (success) {
 5        resolve(42); // In case of success
 6    } else {
 7        reject('Failed'); // In case of failure
 8    }
 9});
10
11myPromise
12    .then((value) => {
13        console.log(`Success: ${value}`);
14        return value + 1; // Pass the value to the next then
15    })
16    .then((newValue) => {
17        console.log(`New value: ${newValue}`);
18    })
19    .catch((error) => {
20        console.error(`Error: ${error}`);
21    });

async/await:

TypeScriptでは、async/awaitを使ってPromiseをより直線的に扱うことができます。async関数内でawaitキーワードを使うと、Promiseの結果を待つことができます。

 1const myPromise = new Promise<number>((resolve, reject) => {
 2    // Perform asynchronous operations
 3    const success = true; // This is just an example
 4    if (success) {
 5        resolve(42); // In case of success
 6    } else {
 7        reject('Failed'); // In case of failure
 8    }
 9});
10
11async function asyncFunction() {
12    try {
13        const value = await myPromise;
14        console.log(`Success: ${value}`);
15    } catch (error) {
16        console.error(`Error: ${error}`);
17    }
18}
19
20asyncFunction();

Promiseのメソッド

Promise.all()

Promise.allは、複数のPromiseを並行して実行し、全てが成功するまで待ちます。

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • 全てのPromiseが成功した場合のみthen()が呼ばれます。1つでも失敗すると、catch()が呼ばれます。

Promise.race()

Promise.raceは、複数のPromiseのうち、最も早く完了したものの結果を返します。

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • この例のように、最初に完了したPromiseの結果が返されます。

Promise.allSettled()

Promise.allSettledは、複数のPromiseが全て完了するのを待ち、成功/失敗の両方を含む全ての結果を配列で返します。

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • すべての Promise が完了(成功または失敗)した時点で then() が呼ばれます。各結果には status プロパティ('fulfilled' または 'rejected')が含まれます。失敗しても他の処理には影響しません。

Promise.any()

Promise.anyは、複数のPromiseが最初に成功するまで待ち、それを返します。

 1const promise1 = new Promise((resolve) => setTimeout(() => resolve("A ok"), 300));
 2const promise2 = new Promise((_, reject) => setTimeout(() => reject("B fail"), 100));
 3const promise3 = new Promise((resolve) => setTimeout(() => resolve("C ok"), 200));
 4
 5Promise.any([promise1, promise2, promise3])
 6    .then(value => {
 7        // Logs the first fulfilled value ("C ok")
 8        console.log("first fulfilled:", value);
 9    })
10    .catch(err => {
11        console.log("should not reach here in this example:", err);
12    });
  • 複数のPromiseのうち最初に成功した値を返します。

まとめ

TypeScriptを用いることでPromiseの型を適切に指定でき、より型安全なプログラムを書くことができます。これは、Promiseによって返される値の型を予め指定することで、開発時にエラーを早期にキャッチするのに役立ちます。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video