Javaエンジニアのための非同期処理入門:JavaScriptのPromiseとasync/awaitを徹底解説!

こんにちは。ゆうせいです。
今回はJavaを学んだ新人エンジニアに向けて、JavaScriptの非同期処理について、丁寧にわかりやすく解説します!

「JavaScriptは非同期が普通って聞いたけど、なんで必要なの?」
「Promiseとかasync/awaitってどう使うの?」

こんな疑問、よくありますよね。この記事では、Javaと比較しながら、非同期の考え方から具体的なコードの使い方までしっかり説明していきます!


なぜ非同期処理が必要なのか?

JavaScriptは基本「シングルスレッド」

JavaScriptはシングルスレッド(1つの処理の流れ)で動く言語です。
つまり、何か時間がかかる処理(例:ファイル読み込み、ネット通信など)を待っている間、他の処理が止まってしまうのです。

たとえばこんなコード(同期的な処理)

const data = fetchData(); // 時間がかかる処理
console.log("処理が終わった");

fetchData() に時間がかかると、次の console.log も待たされます。
これではユーザーの操作がフリーズしてしまうことも…。

そこで使われるのが非同期処理です!


JavaとJavaScriptの非同期処理の違い

比較項目Java(例:CompletableFutureJavaScript(例:Promise
スレッド数複数スレッドシングルスレッド+非同期処理
実行形式並列(スレッドプール)非同期でコールバック管理
コーディングの直感さやや複雑async/awaitで直感的

Promiseとは?

「約束された未来の値」

Promise(プロミス)とは、将来完了するかもしれない非同期処理の結果(成功 or 失敗)を表すオブジェクトです。

イメージとしては、Amazonで商品を注文して、届くのを待ってる状態です。

const promise = new Promise((resolve, reject) => {
  // 非同期処理(例:通信)
  if (成功) {
    resolve(結果);
  } else {
    reject(エラー);
  }
});


thenとcatchでPromiseを扱う

fetchData()
  .then(result => {
    console.log("成功:", result);
  })
  .catch(error => {
    console.log("失敗:", error);
  });

  • then(...):成功時に呼ばれる
  • catch(...):失敗時に呼ばれる

async/awaitで直感的に書く

Promiseは便利ですが、ネストが深くなると読みにくいという欠点があります。
そこで登場するのが、async / await 構文です。

実際のコード例

async function loadData() {
  try {
    const result = await fetchData();
    console.log("成功:", result);
  } catch (error) {
    console.log("失敗:", error);
  }
}

書き方のポイント

  • 関数の宣言に async を付けると、その関数は必ずPromiseを返す
  • awaitPromiseが解決されるのを待つ記法
  • try/catch でエラーもきれいに扱える

具体例:APIデータ取得の違い

Javaの場合(非同期処理:CompletableFuture

CompletableFuture.supplyAsync(() -> fetchData())
    .thenAccept(data -> System.out.println(data));

JavaScript(async/await)

async function main() {
  const data = await fetchData();
  console.log(data);
}

JavaScriptの方が、まるで同期処理のような書き方ができて読みやすいですね。


非同期処理に関する注意点

注意点内容
awaitasync関数の中でしか使えないグローバルスコープで直接使うとエラーになります
Promiseは常に「非同期」すぐに結果が返っても、then/catchは次のTickで呼ばれる(イベントループの都合)
複数の非同期を同時実行したいときPromise.all()Promise.race() を使う

図解:Promiseとasync/awaitの対応関係

処理の目的Promise構文async/await構文
成功したとき.then(data => {...})const data = await fetchData()
エラーを処理したい.catch(error => {...})try { ... } catch (e) { ... }

今後の学習ステップ

JavaScriptの非同期処理を深めるには、次のステップがオススメです!

  1. Promise.all()Promise.race() の使い方
  2. fetch() を使って本物のAPI通信に挑戦
  3. 非同期処理とDOM操作を組み合わせた小さなアプリを作ってみる

まとめ

JavaScriptの非同期処理は、最初こそ難しく見えますが、Promiseとasync/awaitを理解すればとても強力な道具になります。
Java経験があるなら、非同期の考え方はすでに知っているはずなので、あとは構文に慣れるだけ!

今後は非同期処理を活用して「Web API」「データの読み込み」などにどんどんチャレンジしていきましょう!

次は「Promise.allを使った複数非同期処理の制御」なども学ぶと、より実践的になりますよ!

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。