ことれいのもり

JavaScriptのasync/awaitについて簡単にまとめてみた

はじめに

非同期処理として使われている async / await について簡単にまとめてみました。

この記事では、ゲームの「ジャンプしてコインを取る」という操作を例に説明していきます。

前提

言語: JavaScript

参考リンク

同期処理と非同期処理

同期処理と非同期処理を図にまとめるとこのようなイメージです。

「プレイヤーがジャンプでコインを取得する」という操作を例に考えてみましょう。

同期処理の画像

同期処理は、処理が完了するまで次の処理に進めません。

自分が意図した挙動と異なる可能性があります。

非同期処理の画像

一方非同期処理は処理を待たずに次の処理に進みます。

ここでのポイントは、止まっている処理は後から結果を受け取れるということです。

「接触した相手が敵なのかコインなのか」を受け取り、内容に応じて処理を分けることができます。

非同期処理は便利ですが、コードが読みづらくて処理の流れが分かりにくいです。

非同期処理を同期処理のように書くことができるのが、async/await です。

async / await で非同期処理を書く

非同期処理を実際に書いてみます。

非同期処理をしたい関数名の前に async をつけて、その関数を呼び出す前に await をつけるだけです。

// ジャンプをする
async function jump() {
  console.log("プレイヤーがジャンプを開始");
  return new Promise((resolve) => {
    // ここにジャンプの終了条件が入る
    // 今回は1秒後にジャンプが終わると仮定する
    setTimeout(() => {
      console.log("ジャンプ終了");
      resolve();
    }, 1000);
  });
}

// コインを取る
async function collectCoin() {
  console.log("コインを取る処理を待機");
  return new Promise((resolve) => {
    // ここにコイン取得の判定が入る
    // 今回は0.5秒後にコインを取得すると仮定する
    setTimeout(() => {
      console.log("コイン取得!");
      resolve();
    }, 500);
  });
}

// プレイヤーのアクションを実行する
async function playerAction() {
  await jump();                   // ジャンプが終了するまで待機
  await collectCoin();         // コイン取得が完了するまで待機
  console.log("アクション終了!");
}

// 実行
playerAction();

本来は setTimeout の所にジャンプの終了条件として「地面に接触したら」などの処理が入ります。

しかし今回は仮なので、 1.0 秒後にジャンプが終わったと仮定しています。

実行するとこのように表示されます。

非同期処理の出力結果

ジャンプとコイン取得の処理を待機してから「アクション終了!」が表示されていることが分かりますね。

これは await のところで処理が待機していることを意味しています。

async / await を使うと、非同期処理なのに同期処理のように記述できます。

コードを後から見直したときでも非常に分かりやすいので、ゲーム開発では大活躍しますね!

Promiseとは?

コードの中に出てくる Promise は処理が成功したか失敗したかを表すステータスです。

3つの状態があります。

Promiseの画像

最初は初期状態の pending 状態です。

ここから処理が成功すれば resolve 、失敗すれば reject を返します。

今回はジャンプが終わったので 成功の resolve を返しています。

おわりに

JavaScriptのasync/awaitと、Promiseについてまとめました。

自分でコードを書いて実装してみると理解が深まるので、試行錯誤してみてください。