[JavaScript]Promiseで簡単に非同期通信を実現する...！

# はじめに
個人的に非同期通信にはニガテ意識がずっとありました。
そこで、`Promise`というものを知り、それを理解することで、非同期通信も併せて理解できました！
ここでは、Promiseの使い方を知って、JSの非同期通信の実装方法を学びながら併せて非同期通信についても理解しましょう！

# Promiseとは
Promiseとは、`非同期処理をより簡単に、可読性が上がるように書けるようにしたもの`です。
「非同期処理」と「コールバック処理」を組み合わせはよく使うのですが、構造が複雑化して可読性が低くなる欠点がありました。そこで誕生したのがPromiseです。

## 使い方
基本的な使い方は以下の例の通りです。引数は`resolve`と`reject`を取ります。

- **resolve**
    - 処理成功時に実行する関数。thenにコールバックする。
- **reject**
    - 処理失敗時に実行する関数。catchにコールバックする。
- **finally**
    - Promiseオブジェクトが処理され終了する前に実行される処理。
    - 引数を取ることが出来ない。

```js
new Promise(function(resolve, reject) {
  resolve('成功');
  reject('失敗');
}).then(function(data) {
  console.log(data); // => "成功"
}).catch(function(data) {
  console.log(data); // => "失敗"
}).finally(function() {
  console.log('終了'); // => "終了"
})
```

### thenを使用してコールバック処理
Promiseオブジェクトに`then`メソッドを使うことで成功時のコールバック処理を行うことが出来ます。

```js
new Promise(function(resolve) {
  resolve('成功');
}).then(function(data) {
  console.log(data); // => "成功"
})
```

#### Promiseチェーンで処理を連結させる
thenを繋げることで複数の非同期処理を順次実行することが出来ます。これによって、階層構造が複雑化しにくくコードの可読性も上がります。
※thenメソッドの最後にはPromiseオブジェクトを返すようにする。

```js
// Promiseオブジェクトを返す関数を定義
function promise(val) {
  return new Promise(function(resolve) {
    resolve(val);
  })
}

promise(1).then(function(val) {
  console.log('成功その' + val++); // => "成功その1"
  return promise(val);
}).then(function(val) {
  console.log('成功その' + val++); // => "成功その2"
  return promise(val);
}).then(function(val) {
  console.log('成功その' + val++); // => "成功その3"
})
```

#### allで複数のPromiseを実行
`.all()`メソッドを利用することで、複数の非同期処理を実行することもできます。

```js
function sample1s() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve('1秒後に実行');
    }, 1000)
  })
}

function sample3s() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve('3秒後に実行');
    }, 3000)
  })
}

function sample5s() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve('5秒後に実行');
    }, 5000)
  })
}

Promise.all([sample1s(), sample3s(), sample5s()])
.then(function(data) {
  console.log(data);
  console.log('すべての処理が終了しました');
})

// => ["1秒後に実行", "3秒後に実行'", "5秒後に実行'"]
// => "すべての処理が終了しました"
```

### catchを使用してエラーハンドリング
Promiseオブジェクトに`catch`メソッドを使うことでエラーハンドリングを行うことが出来ます。

```js
new Promise(function(reject) {
  reject('失敗');
}).catch(function(data) {
  console.log(data); // => "失敗"
})
```

## 簡単な使い方(Async/Await)
`Async/Await`を利用することで、Promiseによる非同期処理をより簡潔に効率よく記述することが出来ます。

- **Async**
    - 「async」を「function(){ }」の前に記述することで非同期処理を実行できる関数を定義できます。
- **Await**
    - Promise処理の結果が返ってくるまで一時停止してくれる。

```js
// Promiseオブジェクトを返す関数を定義
function samplePromise(message) {
  return new Promise(function(resolve) {
    setTimeout(function() { resolve(message) }, 3000)
  })
}

// async〜で関数を定義
async function sampleAsync() {
  // Promiseオブジェクトが返るまで待機し、返った値を変数に格納
  const result = await samplePromise('成功');
  console.log(result);

}

sampleAsync() // => "成功"
```

# 終わりに
いや〜、ややこしい部分はありますが、非同期通信を簡単に実装できるのは嬉しいですね。。
これからの僕のJS人生は少し色付きました。

# 参考
[Promise]
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)

[【JavaScript】初心者にもわかるPromiseの使い方]
(https://techplay.jp/column/581)

[【JavaScript入門】誰でも分かるPromiseの使い方とサンプル例まとめ！]
(https://www.sejuku.net/blog/52314)

[【JavaScript】Macrotasks と Microtasks]
(https://hidekazu-blog.com/javascript-macrotasks-microtasks/)

[【JavaScript入門】5分で理解！async / awaitの使い方と非同期処理の書き方]
(https://www.sejuku.net/blog/69618)