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

この記事は下記の方がおすすめ!
- 非同期処理ってなに?
- async/awaitってなに?
- async/awaitとPromiseの違いとは?
Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち
非同期処理ってなに?
「非同期処理」とは、時間のかかる処理を待っている間に、他の作業を進められるようにする仕組みです。
例:サーバーからデータを取得する場合
通常のウェブサイトでは、次のようなことがよくあります
- サイトを開くときに、サーバーからデータを取りに行く
- この取得に数秒かかることもある
- もしデータを待っている間に画面が止まっていたら、ユーザー体験が悪くなる
そこで使われるのが「非同期処理」です。
非同期処理にすると、データを待っている間にも他の操作を続けることができます。ユーザーにとってスムーズな体験を実現できるのです。
Promise(プロミス)とは?
あとで「結果が返ってくるよ!」と約束してくれる仕組みです。
JavaScriptでは、時間がかかる処理(たとえば fetch や setTimeout)に対して、 「すぐには結果が出ないけど、終わったら結果を返すね!」という 箱 を渡してくれます。
Promiseの状態は3つ
Promise は、非同期処理の進行に応じて、下記のいずれかの状態を取ります。
項目 | 状態 |
---|---|
| ⏳ 実行中 |
| ✅ 完了 |
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型かどうか」を見分けるには?
- 関数の仕様を調べる
- 公式ドキュメントや型定義に
Promise
と書かれていれば、Promise型の返り値です。 - 例:
fetch()
やaxios.get()
は Promise を返すと明記されています。
- 公式ドキュメントや型定義に
- 関数の型アノテーション(TypeScript)
function getData(): Promise<string> { ... }
のようにPromise<型>
と書かれていれば、明確に Promise型です。
- 返り値に .then() を使ってみる(最終手段)
- 実際に
.then()
をつけて動作するか試すと、Promise型かどうかがわかります(ただし危険なので1と2が推奨)
- 実際に
async / await とは?
.then()
だけだと、処理が長くなると読みづらくなります。 それをもっと“ふつうの順番”っぽく書けるようにしたのが、async
と await
です。
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 { … } とは?
非同期処理をしていると、失敗することもあります。 たとえば、サーバーが止まっていたり、ネットがつながっていなかったりする状況です。
そんなときに、エラーが出てプログラムが止まらないようにするための仕組みが、 try
と catch
です。
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/catch | async/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
の結果「こんにちは、太郎さん」が画面に表示される

.catch() でエラー表示
// 省略...
const mockFetchUser = () =>
Promise.resolve({ json: () => Promise.resolve({ name: "" }) });
// 省略...
✅ 表示結果mockFetchUser
関数 → res.json()
→ data.name
が undefined
または false のため、someAsyncOperation
は reject("名前がありません")
を返し、.catch()
により「中のエラー: 名前がありません」が画面に表示される。

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

コメント