JavaScriptの非同期処理(promise,await,asyncの使い方)

# 同期処理と非同期処理
***同期処理とはコードの順番通りに処理が実行されます***。(基本プログラムは上から下に実行されます)
***非同期処理はコードが書かれた順番通りに出力されないこと***です。

## 非同期処理で動かす
実際にコードで動かしてみました。

```js
setTimeout(() => {}, 1000);//1000ミリ秒たった後にコールバック関数が実行
```
コールバック関数の中に出力します。
```js
let A = 0;

setTimeout(() => {
  A = 100;
}, 1000); //1000ミリ秒たった後にコールバック関数が実行

console.log(A);
//0
```
***1000ミリ秒経つまで実行されないので0に***なっています。

## Promise
JavaScriptは非同期言語なので、一つ前の実行に時間がかかったり、実行完了をまたずに次の処理が行われたりします。その時に使うのが```Promise```です。

```main.js
console.log("1番バッター");

setTimeout(() => {
  console.log("2番バッター(1秒後に実行)");
}, 1000); //1000ミリ秒たった後にコールバック関数が実行

console.log("3番バッター");
//1番バッター
//3番バッター
```
このように2番バッターが出力されないような処理になってしまいますが、
***Promise***を使うと、```処理の順序に「約束」を付けることができます。```

### promiseの使い方

```main.js
console.log("1番バッター");

// 約束を付けたい処理にPromiseを使う、インスタンス化
new Promise((resolve, reject) => {
  //1秒後に実行する処理
  setTimeout(() => {
    console.log("2番バッター(1秒後に実行)");
    //無事処理が終わったことを伝える
    resolve();
  }, 1000);
}).then(() => {
  // 処理が無事終わったことを受けとって実行される処理
  console.log("3番バッター");
});

//1番バッター
//2番バッター(1秒後に実行)
//3番バッター
```
***Promiseのおかげで思った通りの処理***ができました。

### rejectも実行
rejectの実行法も見ていきます。***基本不具合が発生した時に使い***ます。
```main.js
new Promise((resolve, reject) => {
  //1秒後に実行する処理
  setTimeout(() => {
    console.log("2番バッター(1秒後に実行)");
    //無事処理が終わったことを伝える
    reject();
  }, 1000);
})
  .then(() => {
    // 処理が無事終わったことを受けとって実行される処理
    console.log("3番バッター");
  })
  .catch(() => {
    console.log("catch実行");
  });
//1番バッター
//2番バッター(1秒後に実行)
//catch実行
```
***.catchを上のように使い、thenの処理は実行されず、catchの処理が実行***されます。

もう少し簡単な処理もします。
```main.js
const promise = new Promise((resolve, reject) => {
  reject();
})
  .then(() => {
    console.log("resolveするぞ");
  })
  .catch(() => {
    console.log("rejectした");
  });

// rejectした

```
.thenが実行されずcatchが実行されました。

# Promiseには3つの状態
Promiseには、PromiseStatusというstatusがあり、3つのstatusがある見たいです。

```pending```: ***未解決 (処理が終わるのを待っている状態)***
```resolved```: ***解決済み (処理が終わり、無事成功した状態)***
```rejected```: ***拒否 (処理が失敗に終わってしまった状態)***

```new Promise()```で作られたPromiseオブジェクトは、```pendeing```という
```PromiseStatus```で作られます。

処理が成功した時に、```PromiseStatus```は```resolved```に変わり,
```then```に書かれた処理が実行されます。
処理が失敗した時は、
```PromiseStatus```が```rejected```に変わり、```catch```に書かれた処理が実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/b4bead07-beb3-8055-117d-6ad2187cd9ea.png)

> 引用　https://qiita.com/cheez921/items/41b744e4e002b966391a#promise%E3%81%AB%E3%81%AF3%E3%81%A4%E3%81%AE%E7%8A%B6%E6%85%8B%E3%81%8C%E3%81%82%E3%82%8B

***上記文章も引用***しました。

# async/await
```async```と```await```を使うとpromiseをもっと簡単に書けます。
```async```は***非同期関数を定義する関数宣言であり、関数の頭につけます。***
awaitは、Promiseオブジェクトが値を返すのを待つ演算子で、
awaitは必ず、async function内で使います。

```main.js
const lateTrain = (minitues) => {
  new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, minitues);
  }).then(() => {
    console.log(`電車が${minitues}分遅れた`);
  });
};
```
これを使ってPromiseの処理をasync/awaitで、リファクタリングします。

```main.js
const lateTrain = async (minitues) => {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, minitues);
  });
  // Promiseの結果が返ってくるまで実行されない
  console.log(`電車が${minitues}分遅れた`);
};
```

最後にこの処理も実行します。
```main.js
let A = 0;

init();
async function init() {
  try {
    const result = await new Promise((resolve, reject) => {
      setTimeout(() => {
        a = 1;
        reject(A);
      }, 1000);
    });
    console.log(result);
  } catch (e) {
    console.log("catchが実行", e);
  }
}
//catchが実行 0
```
少し遅れて実行されます。



# 資料

[小学生でもわかるasync/await/Promise入門【JavaScript講座】](https://www.youtube.com/watch?v=kbKIENQKuxQ)

[【JavaScriptの基本】Ajax入門講座｜非同期通信とAjaxとは](https://www.youtube.com/watch?v=V89nh3UCBbM)


https://qiita.com/ryosuketter/items/dd467f827c1b93a74d76#%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8


https://developer.mozilla.org/ja/docs/Web/API/setTimeout

https://qiita.com/cheez921/items/41b744e4e002b966391a