[Javascript]コールバックヘルからの帰還。Promise/Async/Awaitを考えるよ。

#Promise, Async, Await　
以前に書いたように、Promiseはコールバック地獄に落ちたプログラマーを救うために現れた救世主である。 
で、***その正体はただのオブジェクトだ。*** 
これが結構重要。なので、**Promiseが返ってくる** というよく分からない表現は、単にPromiseというオブジェクトが返ってくると考えれば良い。(Promiseが何かよく分からなかった時、調べる度にPromiseとは値ではなくPromiseを返すのがPromiseなのだ！って説明されていて、そもそもPromiseが分からないのに、その分からないものを返すものとかってだから何やねん！ってPCの前で憤慨した思い出)
で、その後に便利なPromiseを色々な関数に適応できるようにして、使い勝手を良くしたのがAsync/Awaitである。 
これを使うと、普通の関数をPromise関数に変換できるのである。 
簡単な例で説明しよう。 

```js
const hello = (name) =>{
  return `Hello ${name}`
}

hello("namahage");


//戻り値 : Hello namahage
```

これはいわゆる普通の関数。ただただ何かの値が返ってくるだけ。 
で、この関数をプロミス関数化したものがこれ。 

```js
const hello = async (name) =>{
  return `Hello ${name}`
}

hello("namahage");
```

関数の前にasyncを付けるだけ！ 
で、何か違うんか？ 
こうすると、***関数実行後にPromiseが返ってくるんじゃ！*** 
Promiseが返ってくるとはなんぞや！？ 
実行結果がこれ。

```js
//戻り値
Promise {<fulfilled>: "Hello namahage"}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "Hello namahage"
```

fulfilledっていう実行結果と、"Hello namahage"というバリューがオブジェクトとして返ってきておるじゃろ。 
さっきの、バリューだけがちょろっと返ってきてるのとは大きな違いじゃ。 
で、このfulfilledっていう合図が、コールバック地獄を抜け出す大きな手段になるのじゃ。 
コールバック、非同期処理をする意味っていうのは、ある順番に沿って関数を実行させていく為じゃの？野菜を洗ったら→刻む→炒める→盛り付ける。 ばらばらじゃと、炒める→盛り付ける→切る→洗う　とかになって、大惨事じゃぁ！ 
例えば、サーバーに何らかのデータを要求する、で、それが戻ってきてからブラウザに表示。っていう場合、ブラウザ表示はデータがちゃんと戻ったよ　という合図があってから実行しないと、何もない画面が表示されるだけじゃ。おまけに、こういうサーバーを通す処理は時間がかかる。 
で、この合図がfulfilled。
そして、Promiseオブジェクト化するっていう事は、thenメソッドを使えて、それを繋げることで今までコールバックでやっていた順番に関数を実行　っていうのが出来るのじゃ。 

```js
const hello = async (name) =>{
  return `Hello ${name}`
}

hello("namahage").then((result)=>{
  console.log(result);
})

// Hello namahage
```  

分かるかの？hello()関数が実行されたあとに、戻り値が自動的に.then関数の引数として渡されるんじゃ。これはまさにコールバック的な動きじゃな。で、このthenもPromiseを返すので、同様に.thenでつないでいけば、多くの関数も連続で順番通りに実行していけるんじゃな。 
で、Promiseは成功時にFulfilled、何かエラーがあった時はrejectを返すと説明したな。 
rejectの時の対応は、thenチェーンの最後に .catch でエラーのハンドリングをするのがお決まりのパターンじゃ。 

```js
const hello = async (name) =>{
  return `Hello ${name}`
}

hello("namahage")
.then((result)=>{
  console.log(result);
})
.catch((error)=>{
  console.log(error)})
}
```  

###Async/Await

で、次は ***await***　じゃ。 
このasync/awaitは前に述べたように、Promise登場数年後にjavascriptに実装されたのじゃが、Promiseをベースに、さらに使い勝手をよくしようという目論見じゃ。 
Promiseのthenチェーンよりもよりシンプルで可読性の良いコードを書けるんじゃ。勿論.thenチェーンとの併用も可能。 
awaitはasyncでPromise化した関数の中でセットで使うことが出来て、その言葉のままじゃな。.thenと似ておって、***fulfilledなりrejectの合図が戻ってくるまで、awaitを付けたコードブロックの実行を待ってくれるのじゃ。*** 
また、[node.jsとは何か](https://qiita.com/monsoonTropicalBird/items/f12848cc5d0cde726d4f)で述べたように、この待ち時間に色々と他の処理を非同期でやってくれるので、CPU負荷も低く、全体のスピードもかなり速くなるのじゃ。 
node.jsはこういう処理をサーバー側でやっておるんじゃの。
 
基本のシンタックス。

```js
let value = await promise;
```

promise関数から合図が返ってくるのを待ち、返ってきた返り値を変数に入れている。 
以下のサンプルコードを見てみよう。 

```js
async function showAvatar() {

  // read our JSON
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();

  // read github user
  let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();

  // show the avatar
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

  // wait 3 seconds
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  img.remove();

}

showAvatar();
```

まず、***javascriptビルドインのfetch()もjson()もすでにPromise関数である。*** つまり、実行後にPromiseがかえってくるのじゃ。　
で、上でやっている事は、ユーザーの情報をとってきて、そのユーザー情報をもとに、githubのプロフィール写真をfetch。 
.json()でフェッチしたJSONをjavascriptオブジェクトに変換。
全ての素材がそろったら、画像を表示して、３秒後に消す。っていう事をやっている。 
fetch()は素材をとってくるのに時間がかかるから、Promiseでの非同期処理が必須になってくる。Promiseなかったら、データが届いて無いから、写真が表示されなかったりエラーになったりするからの。 
では、そろそろバイトの時間なので、これくらいにしとくぞ。  

コード参照：
https://javascript.info/async-await