async/awaitとPromiseの違いとは?

async/awaitとPromiseの違いとは? JavaScript
async/awaitとPromiseの違いとは?
この記事は約13分で読めます。

でじぼうです。

この記事では、JavaScriptの中でもつまずきやすい「非同期処理」について、丁寧に解説します。

でじぼう
でじぼう

この記事は下記の方がおすすめ!

  • 非同期処理ってなに?
  • async/awaitってなに?
  • async/awaitとPromiseの違いとは?

Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち

非同期処理ってなに?

「非同期処理」とは、時間のかかる処理を待っている間に、他の作業を進められるようにする仕組みです。

例:サーバーからデータを取得する場合

通常のウェブサイトでは、次のようなことがよくあります

  1. サイトを開くときに、サーバーからデータを取りに行く
  2. この取得に数秒かかることもある
  3. もしデータを待っている間に画面が止まっていたら、ユーザー体験が悪くなる

そこで使われるのが「非同期処理」です。

非同期処理にすると、データを待っている間にも他の操作を続けることができます。ユーザーにとってスムーズな体験を実現できるのです。

Promise(プロミス)とは?

あとで「結果が返ってくるよ!」と約束してくれる仕組みです。

JavaScriptでは、時間がかかる処理(たとえば fetch や setTimeout)に対して、 「すぐには結果が出ないけど、終わったら結果を返すね!」という を渡してくれます。

Promiseの状態は3つ

Promise は、非同期処理の進行に応じて、下記のいずれかの状態を取ります。

項目状態
pending(ペンディング)⏳ 実行中
fulfilled(フルフィルド)✅ 完了
rejected(リジェクテッド)❌ エラー

.then() / .catch() の使い方

Promise が返される処理には、結果が返ってきたあとにどう処理するかを .then().catch() で書くことができます。

fetch("https://example.com")
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((error) => console.error("失敗しました", error));
  • .then() は「成功したらこれをしてね」
  • .catch() は「失敗したらこれをしてね」

このように、Promiseの結果に対して、処理を“つなげて”書けるのが特徴です。

なぜ .then() / .catch() が使えるの?

それは、返り値が「Promise型」だからです。

JavaScriptでは、.then().catch()Promise型の値にしか使えません

.then() を使えるのは Promise型 だけです。

const result = fetch("https://example.com");
console.log(result); // → Promise { <pending> }

❌ Promise を返さない関数に .then() は使えない

function greet() {
  return "こんにちは"; // ただの文字列
}

greet().then((msg) => console.log(msg)); // ❌ エラー!

返り値を見ずに「Promise型かどうか」を見分けるには?

  1. 関数の仕様を調べる
    • 公式ドキュメントや型定義に Promise と書かれていれば、Promise型の返り値です。
    • 例:fetch()axios.get() は Promise を返すと明記されています。
  2. 関数の型アノテーション(TypeScript)
    • function getData(): Promise<string> { ... } のように Promise<型> と書かれていれば、明確に Promise型です。
  3. 返り値に .then() を使ってみる(最終手段)
    • 実際に .then() をつけて動作するか試すと、Promise型かどうかがわかります(ただし危険なので1と2が推奨)

async / await とは?

.then() だけだと、処理が長くなると読みづらくなります。 それをもっと“ふつうの順番”っぽく書けるようにしたのが、asyncawait です。

async function loadData() {
  const res = await fetch("https://example.com");
  const data = await res.json();
  console.log(data);
}
  • async は「この関数は非同期(Promise)を使うよ」と宣言するもの
  • await は「この処理が終わるまで“ちょっと待って”ね」という意味

注意:await は async がついた関数の中でしか使えない

await は、「Promiseの結果を待つ」キーワードですが、 それ単体では使えず、必ず async 関数の中で使う必要があると覚えておきましょう。

✅ 正しい書き方(async 関数の中で await を使う)

async function getData() {
  const result = await fetch("https://example.com");
  const json = await result.json();
  console.log(json);
}

❌ エラーになる例(関数の外で await を使っている)

const result = await fetch("https://example.com");

try { … } catch { … } とは?

非同期処理をしていると、失敗することもあります。 たとえば、サーバーが止まっていたり、ネットがつながっていなかったりする状況です。

そんなときに、エラーが出てプログラムが止まらないようにするための仕組みが、 trycatch です。

async function getData() {
  try {
    const res = await fetch("https://example.com");
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error("エラーが起きました:", err);
  }
}
  • try の中に「失敗するかもしれない処理」を書く
  • catch の中に「失敗したときにどうするか」を書く

.catch() と try/catch の違いは?

どちらも「エラー処理」ですが、使い方が違います。

.then() を使うなら .catch() を、 await を使うなら try/catch を使うのが基本の形です。

項目使える場面処理の書き方
.catch().then() で書く場合.then().catch()
try/catchasync/await で書く場合try { await ... } catch {}

async/await・.then()/.catch()・try/catch を全部使った例

下記のコードは、Reactを使って非同期処理の動作を試すサンプルアプリです。
簡単にいうと、「ユーザー情報を取得 → その名前を使ってあいさつ文を表示」する処理です。

言語:JavaScript
ライブラリ:React

正常終了

import React, { useEffect, useState } from "react";

function App() {
  const [msg, setMsg] = useState("");

  useEffect(() => {
    (async () => {
      try {
        const res = await mockFetchUser();
        const data = await res.json();
        someAsyncOperation(data)
          .then(setMsg)
          .catch((e) => setMsg("中のエラー: " + e));
      } catch (e) {
        setMsg("fetchのエラー: " + e);
      }
    })();
  }, []);

  return (
    <div>
      <h1>React 非同期処理テスト</h1>
      <p>{msg}</p>
    </div>
  );
}

const mockFetchUser = () =>
  Promise.resolve({ json: () => Promise.resolve({ name: "太郎さん" }) });

const someAsyncOperation = (d) =>
  d.name
    ? Promise.resolve("こんにちは、" + d.name)
    : Promise.reject("名前がありません");

export default App;

✅ 表示結果
mockFetchUser 関数 → res.json()data.name"太郎さん" のため、
someAsyncOperation の結果「こんにちは、太郎さん」が画面に表示される

async/awaitとPromiseの違いとは?

.catch() でエラー表示

// 省略...
const mockFetchUser = () =>
  Promise.resolve({ json: () => Promise.resolve({ name: "" }) });
// 省略...

✅ 表示結果
mockFetchUser 関数 → res.json()data.nameundefined または false のため、
someAsyncOperationreject("名前がありません") を返し、
.catch() により「中のエラー: 名前がありません」が画面に表示される。

async/awaitとPromiseの違いとは?

例外発生のため try/catch でエラー表示

// 省略...
const mockFetchUser = () => Promise.reject("ネットワークエラー");
// 省略...

✅ 表示結果
mockFetchUser 関数が reject("ネットワークエラー") を返したため、
await mockFetchUser() で例外が発生し、
catch により「fetchのエラー: ネットワークエラー」が画面に表示される。

async/awaitとPromiseの違いとは?

コメント

タイトルとURLをコピーしました