げっとシステムログ

WEB開発メモ

JavaScript の async/await について

AWS Lambda の初期コードに async が使われていた。 これがよくわかっていなかったために数時間グダッたのでここに記録しておく。

CONTENTS
  1. この記事の内容
  2. async について
  3. await について
  4. async/await の使い所
  5. まとめ
  6. 参考資料
ENVIRONMENTS
  • Node.js 10.16.0

この記事の内容

ほぼ下記の記事と同じ内容。 これらを読んで自分なりにまとめなおしたもの。

TOP

async について

async キーワードを function の前につけることで、その関数は Promise を返すようになる。

const func = async () => {
  return 1;
}

これは下記のコードと同様。

const func = () => {
  return new Promise((resolve, reject) => {
    resolve(1);
  });
}

TOP

await について

Promise を await すると、その Promise の結果が返ってくるまでその場で待つ。

これは async をつけた関数の中でのみ使用可能。

const func = async () => {
  const response = await fetch("https://example.com");

  console.log(response.status);

  return response.body.text();
}

これは下記のコードと同様。

const func = () => {
  return fetch("https://example.com").then((response) => {
    console.log(response.status);

    return response.body.text();
  });
}

await をいくつか続けて書くこともできる。

const func = async () => {
  const first = await fetch("https://example.com/first");
  console.log(first.status);

  const second = await fetch("https://example.com/second");
  console.log(second.status);

  return {
    first,
    second,
  };
}

この場合、実行は直列化される。

const func = () => {
  return fetch("https://example.com/first").then((first) => {
    console.log(first.status);

    return fetch("https://example.com/second").then((second) => {
      console.log(second.status);

      return {
        first,
        second,
      };
    });
  });
}

TOP

async/await の使い所

async/await について、以下のように感じた。

  • async は関数内で await を使いたいときに使用する
  • await はかなり便利

しかし、async/await地獄 : Qiita では、await はうまく使わないと効率がよくないと書いてある。

特に、await を続けて書く場合は注意が必要であるように感じた。 無駄に直列化させないために、Promise.all を使用することを検討したい。

const func = async () => {
  const result = await Promise.all([
    fetch("https://example.com/first"),
    fetch("https://example.com/second"),
  ]);

  console.log(result[0].status); // first
  console.log(result[1].status); // second

  return {
    first: result[0],
    second: result[1],
  };
}

TOP

まとめ

AWS Lambda で、Slack Bot をやろうと思ってコードを書き始めた。 イベントの内容によって fetch する、という簡単な内容だったのでテストもそこそこにデプロイしつつデバックしていた。 デプロイするのに時間がかかる上、 async/await も理解していなかったおかげで、なんで動かないのか気づくのに数時間かかってしまった。 時間がかかるので、隣のディスプレイでアニメを流しながら作業していたこともあって相当グダグダやっていた。

結局、fetch の結果を待たずに処理を終えていることが原因だった。 (async/await 関係ないね)

テストを十分揃えてからデプロイするようにしよう、と心に硬く誓うのであった。

TOP

参考資料

TOP