Promise, async, awaitについて

# はじめに

どうも、エンジニアのTomoyaです。
今までQiitaで記事を書いたことがなかったので、今回はQiitaで簡単な記事を書いてみようと思います。

# async, awaitについて

async, awaitは理解しがたいところの一つだと思います。そうしたasync, awaitについて解説します。
まず、「async,await」を理解する前にはPromiseを理解することが必要です。
「async, await」はPromiseを簡単に実現したものです。

### 非同期処理
非同期処理とは、ある処理が終わるのを待たずに、次の処理を継続するものです。何かの処理が処理中でも、いったん別の処理を進めておきます。

### Promise
Promiseの持つメソッドやasync・awaitを使うと、非同期処理の結果を待ってから次の処理を実行したり、複数の非同期処理を順番に決めて実行することができます。

# Promiseの例
```js

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Hello, this is a resolved message!");
  }, 3000);
});

// Promiseの結果を処理する
myPromise
  .then((message) => {
    // resolveが呼ばれた場合の処理
    console.log(message);
  })
  .catch((error) => {
    // rejectが呼ばれた場合の処理
    console.error(error);
  });

```

この例だと、Promiseが実行されるとsetTimeoutが非同期処理されます。setTimeoutは3秒間待機する非同期関数です。この場合、setTimeoutが処理を完了する、すなわち3秒間待機するまで他の処理の実行は行われず、3秒間経ってから他の処理が行われます。
それによって、3秒経過した後、成功メッセージHello, this is a resolved message!が呼び出されます。
そして、成功メッセージが呼び出されたら、Promiseが成功したときに実行されるコールバックであるmyPromise.thenが起動し、コンソールにmessageを表示できます。
これが大まかな流れです。
async・awaitはこうしたPromiseの処理をもっと簡単に書くことができます。

# async・await
### async
- 関数にasyncをつけることでその関数を非同期関数にしてくれて、関数を実行するとPromiseを生成して返してくれます。
- そして、Promiseオブジェクトが持つthen, catch, finallyを使うことができます。
### await
- asyncキーワードが付けられた関数内でのみ、awaitを使用することができます。
- awaitをPromiseオブジェクトの前に付けると、Promiseが解決されるまで関数の実行を一時停止し、その結果を取得します。

```js
async function fetchData() {
  try {
    // fetch APIを使用してデータを取得
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
    // レスポンスをJSONとして解析
    const data = await response.json();
    // 結果をコンソールに出力
    console.log(data);
  } catch (error) {
    // エラーが発生した場合の処理
    console.error('Error fetching data:', error);
  }
}

// 関数を呼び出し
fetchData();

console.log("This will log before the fetch completes");

```

このコードの例では、まず、asyncを使うことで非同期関数を定義しています。
そしてこの関数内でawaitを使うことができます。

- respnse関数、data関数ではそれぞれ、awaitが使われているため、それぞれの処理が完了してから先に進みます。

このようにasync・awaitを使うことで非同期処理の完了を待ってから次の処理を行うため、より直感的で読みやすいコードを書くことができます。


# なんで非同期処理を使うの？

結局1つ1つ処理を実行していくのなら、非同期処理じゃなくて同期処理で良くない？と思われるかもしれませんが、非同期処理を使用することには大きなメリットがあります。
それは、非同期処理をすることによって、複数のタスク・リクエストをアプリケーションが同時並行的に実行することができるのです！

以下の二つのパターンで比べてみましょう
### 同期的な例
``` js
function fetchDataSync() {
  const result1 = fetch('https://jsonplaceholder.typicode.com/posts/1').then(response => response.json());
  const result2 = fetch('https://jsonplaceholder.typicode.com/posts/2').then(response => response.json());

  result1.then(data1 => {
    console.log('Data 1:', data1);
    result2.then(data2 => {
      console.log('Data 2:', data2);
    });
  });
}

fetchDataSync();

```
これだと、result1とresult2が順番に実行されます。つまり、result1の処理が完了してからresult2の処理が始まります。そのため、全体の処理が完了するまでに時間がかかります。

### 非同期的な例
``` js
async function fetchDataAsync() {
  const promise1 = fetch('https://jsonplaceholder.typicode.com/posts/1').then(response => response.json());
  const promise2 = fetch('https://jsonplaceholder.typicode.com/posts/2').then(response => response.json());

  const [data1, data2] = await Promise.all([promise1, promise2]);

  console.log('Data 1:', data1);
  console.log('Data 2:', data2);
}

fetchDataAsync();

```

このように、asyncとawaitを使うことで、promise1とpromise2が並行して実行されます。これにより、全体の処理時間が短くなります。

### おわりに
以上がPromise,async・awaitに関する説明です。読んでいただきましてありがとうございました！更なる理解に努めていきます！