JSの非同期処理（Promise、async、await）についてまとめてみた

#はじめに
JSを学習するにあたり、非同期処理（`Promise`、`async`、`await`等）について理解ができてないので簡単にまとめてみました。

「そもそも非同期処理って何？？」って、最初は疑問をもつと思います。
なので、まずは概念的な部分からさぐっていき、JSの非同期処理の定番である`Promise`、`async`、`await`についてまとめていきます。


#概念（同期処理、非同期処理）
`同期処理`はプログラムを上から順に処理していくこと。ひとつの処理が完了するまで次の処理は行われません。
`非同期処理`は同期処理とは違って、ひとつの処理を行っている間、別の処理を並行して行えます。

その２つの違いをわかりやすく日常的なことを取り入れて、図解にすると下の違いです。

```
同期処理　　　　　　　　　　　　　　非同期処理

掃除　　　Netflixみる　　　　　　掃除　　Netflixみる
｜　　　　　　　　　　　　　　　　　　｜　　　　　　
｜　　　　　　　　　　　　　　　　　　｜　　　　　　
｜ーーーーーー｜　　　　　　　　　　　｜ーーーーーー｜
中断　　　　　｜　　　　　　　　　継続｜　　　　　　｜
　　　　　　　｜　　　　　　　　　　　｜　　　　　　｜
｜ーーーーーー｜　　　　　　　　　　　｜ーーーーーー｜
｜　　　　　　　　　　　　　　　　　　｜　
｜　　　　　　　　　　　　　　　　　　｜

```
このようにみると、日常が非同期処理だと楽ですよね。同期処理とは違って、実行完了を待たずに処理を実行しています。

##改めてJSが言う非同期処理とは
・Web API（通信が発生する処理）
・データベース通信
・実行完了を待たない
などの以上のことが可能です。

コードで簡単に記述していくと、

```javascript

  //非同期処理
console.log(1)

setTimeout(function() {
    console.log(2)
},1000)   //１秒後出力

console.log(3)

// 結果
１
３
２
```
と３の数字が先にきていることがわかります。

非同期通信メソッドである、`fetch`を利用していく例だと、、

```javascript

const fetchFunc = () => {
    const url = '外部API(https://..........)'

    // APIへの非同期処理
    fetch(url).then(response => {
        console.log("非同期処理が完了しました！")
        return '完了'
    })
    .catch(() => {
        console.error('非同期処理が失敗です。')
        return '失敗！'
    })
}

const message = '非同期処理'
const result = fetchFunc()
console.log(message + result)

// 結果
非同期処理undefined
非同期処理が完了しました！
```
`fetchFunc`の結果が`undefined`になり、`message`と`result`を返した値が出ています。
また、`fetch`メソッドは、`url`が取得した値を`response`で呼び出します。


良い面😆
ユーザーを待たせない（外部との通信に時間がかかる間に、ユーザーは別のことに取り掛かりたい）ということが挙げられますが、

悪い面😱
実行完了までにデータが存在しないということです。
例えば、Web APIを叩いた際に、レスポンスがまだ帰ってきてない時に実行完了すると、Web APIのデータが存在せず、レスポンスを待たずにタスクが完了してしまう。

上の例でいくと、APIの非同期処理が後から出力されていることがわかりますね。

その非同期処理を待つ方法としてあげられるのが、`Promise`と`async`,`await`です。
##Promise
非同期処理の状態を表すオブジェクト
ちなみに日本語だと「約束」`Promise`

具体的にいうと、実行完了を待って値を渡してから、次の処理に移ります。

そして、Promiseの状態を表すのが、
・`pending`:非同期処理の実行中の状態
・`fulfilled`:処理が成功した状態 =（`resolve()`メソッド）
・`rejected`:処理が失敗した状態 =（`rejected()`メソッド）
を表します。

非同期関数を書き換えてみると、、

```javascript

// Promise
const promiseFunc = () => {
    return new Promise((resolve,reject) => {
    const url = '外部API(https://..........)'

    fetch(url).then(() => {
        console.log('このPromiseは完了しました！')
        return resolve('完了')
    }).catch(() => {
        console.log('このPromiseは失敗しました！')
        return reject
    })
    })
}

const message2 = 'Promise'

// 非同期処理を実行してthenでチェインする
promiseFunc().then(result => { 
    // resultは引数で、returnした値が帰ってくる（resolve）
    console.log(message2 + result)
})

// 結果
このPromiseは完了しました！
Promise完了
```
`return new Promise((resolve,reject) => {}`と記述することでPromiseができます。
コード中にも記述してありますが、` 関数名.then(引数 => {}) `でチェインして、引数（実行結果）の値を取得します。

##async,await
`Promise`よりもわかりやすい記述で、直感的にわかりやすい。
日本語だと、「非同期」`async`、「待つ」`await`です。

それぞれの役割としては、
・`async` 非同期処理の関数定義につける
・`await` 　〃　　　の実行関数につける
・また、`await`は`async`の関数内でしか使えない
と行った具合になります。

```javascript
// async await
const asyncFunc = async() => {
    const message3 = 'async await'
    const url = '外部API(https://..........)'

    const hoge = await fetch(url).then(() => {
        console.log('このasync,awaitは完了しました！')
        return '完了'
    }).catch(() => {
        console.log('このasync,awaitは失敗しました！')
        return '失敗'
    })
    console.log(message3 + hoge)
return 
}

asyncFunc()
// 結果
このasync,awaitは完了しました！
async await完了

```

`async`関数内で定義したことにより、`fetch`メソッドの前にある`await`が働くことによって、hogeという関数の処理が終わった後に、`console.log`が出力されますね。

#感想
Web APIを操作することを今後、やっていくとなると必ずぶち当たると思うので、要約してみました。async,awaitを少し触った程度の内容ですので、例外処理についてもアウトプットしていきたいです。

##参考にさせていただいたサイト
[https://tech.playground.style/javascript/asynchronous-processing/](https://tech.playground.style/javascript/asynchronous-processing/)