【Javscript】async/awaitを試してみたーawaitについて（No.2）

# 初めに
awaitはasyncで宣言した関数の中でのみ使うことができるということは分かりましたが、そもそも何故asyncで関数を宣言し、awaitを使うのかイマイチ理解できませんでしたのでいろいろ実験してみました。今回は気になったこと、疑問に思ったことについて解説していきます。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

前編：
https://qiita.com/redrabbit1104/items/1ce9f665a0fcd1d99bb2
https://qiita.com/redrabbit1104/items/b8b61a72f849fa3e8881
https://qiita.com/redrabbit1104/items/02bc16cf5abd4ed10ec1

# asyncで宣言した関数はpromiseチェーンが起こるのか？
asyncはpromiseを返すのでthenで繋げるのか試してみました。中身がpromiseの関数にasyncを付けて実験してみました。

```javascript
async function testAsync(speed) {
  return new Promise(resolve => {
    let power = speed * 300;
    resolve(power);
  })
}

testAsync(10).then(result => {
  console.log(result);
  return testAsync(result);
}).then(result2 => {
  console.log(result2);
  return testAsync(result2);
})
```
3000, 90000と予想通りに結果が出力されています。
![スクリーンショット 2021-05-01 8.21.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/4d8cfc3f-eedd-d9ee-9bb9-cb75ada279aa.png)
promiseの挙動と同じであればasyncを付ける必要があるのかという疑問が浮かんできました。awaitはasyncでのみ使うことができると聞いたので、asyncの存在理由はawaitを使うためではないかなと思いました。

# awaitをいろいろ試してみた
awaitは宣言した関数の前に付ければセット完了。また、awaitを使うとpromiseの結果が出るまで処理を行わないことを思い出しました。awaitはasync関数の中でのみ使うことができるので、早速使ってみることに。

```javascript
function insideFunction(speed) {
    return new Promise(resolve => {
      let power = speed * 300;
      console.log(power);
      resolve(power);
    })
}
    
async function aTest() {
    await insideFunction(10);
    insideFunction(0);
    await insideFunction(20);
    insideFunction(0);
    await insideFunction(30);
    insideFunction(0);
   }
aTest();
```
asyncで宣言したaTest関数でinsideFunctionをawaitを付けて呼び出したり付けなかったりを交互にやってみました。
![スクリーンショット 2021-05-01 8.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/1779a70d-2a08-ce59-bbc2-d28470d95ae8.png)
普通に書いた順番通りに実行されています。これではわざわざawaitを使う意味がないんじゃないかと思いました。時間が掛かるような処理だと違いが出てくるのではないかと思い、他の記事にもsetTimeoutを使っていたのでそれを試してみました。awaitを使わない場合と使う場合に分けて実験。

①awaitを使わない場合

```javascript
function waiting(seconds) {
    return new Promise(ok => {
      setTimeout(() => {
        console.log('本当に遅い');
         ok()
        }, 1000 * seconds)
      })
    };

async function aTest2() {
    console.log(1);
    waiting(2);
    console.log(3);
    waiting(3);
    console.log(5);
}
aTest2();
```
![スクリーンショット 2021-05-01 8.48.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/49fd6ab0-4a2e-2663-5e02-825434820987.png)
1,3,5が表示され、その後'本当に遅い'が表示されました。setTimeoutで3秒後、５秒後表示されるようにしたので当たり前の結果です。

②awaitを使った場合
今回はwaiting関数をawaitを付けて実行してみました。

```javascript
function waiting(seconds) {
    return new Promise(ok => {
      setTimeout(() => {
        console.log('本当に遅い');
         ok()
        }, 1000 * seconds)
      })
    };

async function aTest2() {
    console.log(1);
    await waiting(2);
    console.log(3);
    await waiting(3);
    console.log(5);
}
aTest2();
```
![スクリーンショット 2021-05-01 8.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/9f8fcd82-be85-4eea-f86c-b47f3778f217.png)
あれ、先ほどとは結果が違います。書いた順番通りに実行されました。まず'1'が表示され、waiting(2)の実行が完了するまでは'3'が表示されません。その後はwaiting(3)が実行されますが、処理が終わるまでは'5'が表示されません。複数の処理があって、特に時間が掛かる処理があった場合でも書いた順番通りに実行させたい場合に使えると思いました。時間が掛かる処理であればsetTimeoutでなくても、同じような結果が得られるでしょう。

# 結論
asyncを使う理由はpromiseを簡潔に書けるなどの理由のほか、awaitという便利な構文を使うためにあることが理解できました。また、awaitを付けると指定した関数の処理が終わるまで次の関数の処理が行われないということが分かりました。

# 参考サイト
https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
https://qiita.com/soarflat/items/1a9613e023200bbebcb3