【javascript】Promiseの使い方

# Promiseの構造

`Promise`はコンストラクタで作成されます。コンストラクタは、`resolve`と`reject`の2つのコールバック関数を引数として受け取ります。

```javascript
const promise = new Promise((resolve, reject) => {
    // 非同期処理を実行
    const success = true;

    if (success) {
        resolve('成功しました'); // 処理が成功した場合
    } else {
        reject('失敗しました'); // 処理が失敗した場合
    }
});
```

## 状態の詳細

- **Pending（保留中）**：`Promise`が作成された直後の状態。まだ完了も失敗もしていない。
- **Fulfilled（成功）**：非同期処理が成功し、`resolve`が呼ばれた状態。
- **Rejected（失敗）**：非同期処理が失敗し、`reject`が呼ばれた状態。

## thenメソッドとcatchメソッド

`then`メソッドと`catch`メソッドは、`Promise`の状態が変わった後に実行される関数を登録するために使います。

```javascript
promise
    .then((result) => {
        console.log(result); // '成功しました'
    })
    .catch((error) => {
        console.error(error); // '失敗しました'
    });
```

- **`then`メソッド**：`Promise`が成功したときに呼ばれるコールバックを登録します。
- **`catch`メソッド**：`Promise`が失敗したときに呼ばれるコールバックを登録します。

## Promiseのチェーン

`Promise`の強力な機能の1つは、チェーンを作成して非同期処理を連続して実行できることです。

```javascript
const promise = new Promise((resolve) => {
    resolve(1);
});

promise
    .then((result) => {
        console.log(result); // 1
        return result * 2;
    })
    .then((result) => {
        console.log(result); // 2
        return result * 3;
    })
    .then((result) => {
        console.log(result); // 6
    })
    .catch((error) => {
        console.error(error);
    });
```

- 各`then`メソッドは新しい`Promise`を返します。これにより、非同期処理を順次実行できます。

## Promise.all

`Promise.all`は、複数の`Promise`がすべて完了するのを待ちます。すべての`Promise`が成功した場合、成功した結果の配列を返します。1つでも失敗した場合、全体が失敗として処理されます。

```javascript
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve) => {
    setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
    console.log(values); // [3, 42, 'foo']
}).catch((error) => {
    console.error(error);
});
```

- **`Promise.resolve`**：即座に成功する`Promise`を作成します。
- **`Promise.all`**：配列で渡されたすべての`Promise`が成功すると、その結果の配列を返します。

## Promise.race

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

```javascript
const promise1 = new Promise((resolve) => {
    setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve) => {
    setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
    console.log(value); // 'two'
}).catch((error) => {
    console.error(error);
});
```

- **`Promise.race`**：最初に完了した`Promise`の結果を返します。

## エラーハンドリングの強化

`Promise`は、非同期処理のエラーハンドリングを強化するためのものです。`catch`メソッドを使うことで、どのステップでエラーが発生しても適切に処理できます。

```javascript
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('エラーが発生しました');
    }, 1000);
});

promise
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.error(error); // 'エラーが発生しました'
    });
```

- **`catch`メソッド**：チェーンのどこかでエラーが発生した場合に呼ばれます。

## async/await

`async/await`構文は、`Promise`を扱う際にさらに便利です。`async`関数内で`await`を使うことで、非同期処理を同期処理のように記述できます。

```javascript
async function example() {
    try {
        const result = await promise;
        console.log(result);
    } catch (error) {
        console.error(error);
    }
}

example();
```

- **`async`**：関数を非同期関数として定義します。
- **`await`**：`Promise`の完了を待ち、その結果を返します。`await`は`async`関数内でのみ使用できます。