await を一言でいうと
await は、
「Promise の完了を“その行で一旦止まって待ち”、結果の値を取り出すためのキーワード」 です。
await promise と書くと、
- その行で「promise が終わるまで」一旦ストップし
- resolve された値を、その場で普通の値として受け取れます
ここが重要です。await は「処理全体を止める」のではなく、
「その async 関数の“続きを一時停止”して、Promise の完了を待つ」 ものです。
非同期処理を、同期処理のように「上から順番に」書けるようにしてくれます。
await の前提:Promise と async 関数
await は「Promise に対して」使う
await の相手は、基本的に Promise です。
const value = await somePromise;
JavaScriptsomePromise が
new Promise((resolve, reject) => { ... })
JavaScriptのような Promise であれば、
その Promise が resolve されるまで待ち、value には resolve 時の値が入ります。
await は async 関数の中でしか使えない
await は、原則として async 関数の中でしか使えません。
async function run() {
const value = await somePromise;
console.log(value);
}
JavaScript関数の前に async を付けるのは、
「この中で await を使っていいよ」という宣言 だと思ってください。
ここが重要です。await は、「Promise を待つ」+「その関数を一旦止める」ためのスイッチ。
そのスイッチを使える場所が async 関数の中、相手が Promise。
この 2 つの前提は必ずセットで思い出してください。
await の基本動作を具体例で見る
例1:1秒待ってから値を返す Promise を await する
まず、1秒後に解決される Promise を返す関数を用意します。
function wait1sec() {
return new Promise(resolve => {
setTimeout(() => {
resolve("1秒経ちました");
}, 1000);
});
}
JavaScriptこれを await してみます。
async function run() {
console.log("開始");
const message = await wait1sec(); // ここで 1 秒待つ
console.log(message); // "1秒経ちました"
console.log("終了");
}
run();
JavaScript処理の流れはこうです。
run()が呼ばれる"開始"を表示await wait1sec()に到達し、Promise が解決するまでrunの「続き」を一時停止- 1 秒後に
wait1secの Promise が resolve される messageに"1秒経ちました"が入り、処理が再開"1秒経ちました"→"終了"の順で表示
重要なのは、「止まるのは run 関数の中だけ」であって、
ブラウザ全体がフリーズするわけではない ということです。
例2:値を「取り出す」イメージ
Promise を then で書くとこうです。
wait1sec().then(message => {
console.log(message);
});
JavaScript同じことを await で書くと、
const message = await wait1sec();
console.log(message);
JavaScriptとなります。
ここが重要です。await は、「then の中に入っていく」のではなく、
“Promise の中から値を取り出して変数に代入する” イメージです。
これのおかげで、「非同期の結果を使う処理」が、普通の同期コードと同じように書けるようになります。
await を使うと何がうれしいのか
ネストが浅くなり、同期っぽい順序で書ける
Promise を then チェーンで書くとこうなります。
fetch(url)
.then(response => response.json())
.then(data => {
console.log("データ:", data);
})
.catch(err => {
console.error("エラー:", err);
});
JavaScript同じことを async / await で書くと:
async function fetchJson(url) {
try {
const response = await fetch(url);
const data = await response.json();
console.log("データ:", data);
} catch (err) {
console.error("エラー:", err);
}
}
JavaScript「1. fetch して → 2. JSON にして → 3. ログに出す」という順番が、
コードの見た目と素直に一致 します。
直感的な「上から順に実行」が保てる
例えば、3回連続で何かを待ちたい場合。
async function run() {
console.log("1つ目");
await wait1sec();
console.log("2つ目");
await wait1sec();
console.log("3つ目");
await wait1sec();
console.log("完了");
}
JavaScriptコードを上から読むだけで、動きのイメージがそのまま掴めます。
ここが重要です。
await の一番のメリットは、「時間の流れ」をコードの読み順と揃えられること。
「まずこれを待って、そのあとこれをやって…」という処理を、
人間の感覚に近い順番で書けるようにしてくれます。
await とエラーハンドリング(try / catch)
Promise 版:catch でエラー処理
Promise だけで書くと、
someAsync()
.then(result => {
console.log("成功:", result);
})
.catch(err => {
console.error("エラー:", err);
});
JavaScriptawait 版:try / catch で同期コードライクに
await を使うと、
同期コードと同じように try / catch で書けます。
async function run() {
try {
const result = await someAsync();
console.log("成功:", result);
} catch (err) {
console.error("エラー:", err);
}
}
JavaScriptさらに、複数の await にまたがってまとめてエラーを捕まえられます。
async function run() {
try {
const a = await asyncA();
const b = await asyncB(a);
const c = await asyncC(b);
console.log("全部成功:", a, b, c);
} catch (err) {
console.error("どこかでエラー:", err);
}
}
JavaScriptここが重要です。
await を使うと、「成功の流れ」も「エラーの流れ」も、
同期コードとほぼ同じ感覚で書けるようになります。
非同期特有の「then の中の catch の中の…」というネスト地獄から解放されます。
await が返すものと、await し忘れたときの違い
await すると「中身の値」が取れる
Promise をそのまま代入すると:
const dataPromise = fetchJson(url); // Promise
JavaScriptawait で待つと:
const data = await fetchJson(url); // 実際のデータ
JavaScriptdataPromise は「そのうちデータが入る箱」のようなもの。data は「箱から取り出された中身」です。
await を付け忘れると「思ったより早く進む」
よくあるミスのパターン:
async function run() {
const data = fetchJson(url); // await を付け忘れた
console.log(data); // Promise が表示される
}
JavaScriptawait を付け忘れると、
Promise が解決される前に、次の行へ進んでしまいます。
async function run() {
const data = await fetchJson(url); // ここでちゃんと待つ
console.log(data); // 実際のデータ
}
JavaScriptここが重要です。
「その場で結果を使いたい」なら必ず await。
「あとで then で処理したい」なら await なしで Promise のまま持っておく。
「箱のまま扱うのか」「中身を取り出すのか」を意識して使い分けてください。
await と並列実行(あえて await しないテクニック)
直列実行:1つずつ順番に待つ
async function run() {
const a = await taskA();
const b = await taskB();
console.log(a, b);
}
JavaScripttaskA が終わってから taskB が始まるので、
A と B は「直列」です。
並列実行:先に Promise を貯めて、まとめて await
async function run() {
const promiseA = taskA(); // ここで開始
const promiseB = taskB(); // ここでもう開始
const a = await promiseA;
const b = await promiseB;
console.log(a, b);
}
JavaScriptこうすると、
A と B がほぼ同時に進み、
両方の完了をそれぞれ await で待つ形になります。
Promise.all と await の組み合わせ
もっと分かりやすいのは Promise.all です。
async function run() {
const [a, b] = await Promise.all([taskA(), taskB()]);
console.log(a, b);
}
JavaScriptここが重要です。
await は「その場で待つ」ので、付ける場所しだいで
“順番に実行” にも “並列に実行してからまとめて待つ” にもなります。
「これは順番が大事か?」「同時に進めていいか?」を考えて、
どこで await するかを設計するのが、非同期処理の腕の見せ所です。
await とエラー:Promise の reject がどう見えるか
reject された Promise を await すると throw になる
function failAfter1sec() {
return new Promise((_, reject) => {
setTimeout(() => {
reject(new Error("失敗しました"));
}, 1000);
});
}
async function run() {
try {
const result = await failAfter1sec(); // ここで throw される
console.log("成功:", result);
} catch (err) {
console.log("エラーを捕まえた:", err.message);
}
}
JavaScriptawait failAfter1sec() のところで、
内部的には「throw された」のと同じ扱いになります。
だから try / catch で受け止められます。
then / catch と await / try の対応関係を意識する
// Promise 版
someAsync()
.then(result => { ... })
.catch(err => { ... });
// async / await 版
try {
const result = await someAsync();
// ...
} catch (err) {
// ...
}
JavaScriptこの対応をしっかり頭に入れておくと、
Promise ベースのコードを async / await に“翻訳”しやすくなります。
ここが重要です。
await は「resolve された値を取り出す」だけでなく、
「reject されたら throw として扱う」という二面性を持っています。
成功も失敗も、同期コードと同じ感覚で書けるようにしてくれるのが、await の本当の強みです。
初心者として await の役割で本当に押さえてほしいこと
await promise は、「promise が終わるまでその行で待ち、resolve された値を取り出す」。
エラー(reject)のときは、その場で throw されたのと同じになる。
await は async 関数の中でしか使えない。async 関数は「Promise を返す関数」であり、その中だけで await による“一時停止と再開” が起こる。
await を使うと、「非同期処理の順番」を普通の同期コードと同じような見た目で書ける。
try / catch と組み合わせると、then / catch のネストよりずっと読みやすいエラーハンドリングになる。
await を付ける場所しだいで、「直列に一つずつ待つ」のか、「並列に走らせてからまとめて待つ」のかをコントロールできる。
ここが重要です。
await は「Promise を待つための一時停止ボタン」であり、
「Promise の中身をその場で取り出すための道具」です。
コードを書きながら、
“ここでは箱(Promise)のまま扱いたいのか?”
“それとも中身を取り出して次の処理に渡したいのか?”
を意識して、await を置く場所を決めていくと、非同期処理が一気に自分のコントロール下に入ってきます。
最後に、練習として次の 2 つを自分で書いてみてください。
// 1. 1秒後に "A"、さらに1秒後に "B"、さらに1秒後に "C" を順番に表示する async 関数を、await を使って書いてみる。
// 2. A・B・C を「同時に」1秒後に返す Promise にして、
// Promise.all と await を使って、「全部そろったらまとめて表示」する関数を書いてみる。
JavaScript「どこで await するか」を自分なりに試行錯誤してみることが、
await の“本当の役割”を体で理解する一番の近道になります。
