1. 5 件ぶんの合計が返る
  2. 空の配列は 0 件 0 回になる
  3. 表示回数が 0 の 1 件だけのとき
  4. 2 件ぶんの合計が返る
コース一覧
非同期JavaScript:API通信とモジュール
Promise.all で同時に待つ

非同期JavaScript:API通信とモジュール

Promise と async/await、非同期エラー、HTTP/REST、fetch による GET、読み込み・成功・失敗の表示、モジュールの読み方を学ぶ全 19 レッスン(380 分)のコースです。最後は承認済みの読み取り専用 API から作品データを取得して表示します。POST はリクエストの組み立てまでで、外部サービスへの書き込みは行いません。

1
非同期処理
01. 同期と非同期15分
02. Promise をつくって返す20分
03. async と await20分
04. Promise.all で同時に待つ20分
05. 非同期のエラーを捕まえる20分
06. つくる 読み込み中の表示を出す30分
07. 第1章まとめクイズ10分
2
fetch で外のデータを使う
01. HTTP と REST の読みかた15分
02. fetch でデータを取る25分
03. 取ったデータを描画する25分
04. response.ok と失敗時の表示25分
05. POST のリクエストを組み立てる20分
06. つくる 作品データを API から読む30分
07. 第2章まとめクイズ10分
3
モジュールと総仕上げ
01. ファイルを分けるという考えかた15分
02. named export と default export15分
03. つくる ポートフォリオアプリを仕上げる40分
04. ここから先の学びかた15分
05. 第3章まとめクイズ10分

Promise.all で同時に待つ

直列の await と Promise.all
解説

このレッスンで分かること

  • Promise.all は Promise の配列を受け取り、結果の配列を返します
  • 結果の並び順は、渡した配列の並び順のままになります

5 件取るのに、5 回ぶん待っている

前の結果を次に使うなら await を縦に並べるのが正解でした。ところが、互いに関係の無いものまで縦に並べると、待ち時間が丸ごと足し算になります。

JavaScript

// 1 件 80 ミリ秒として、5 件で 400 ミリ秒かかる async function collectIcons(skills) { const icons = []; for (const skill of skills) { icons.push(await fetchIcon(skill)); } return icons; }

for-of の中の await は、1 件が終わってから次を始めます。5 件目に取りかかるのは 320 ミリ秒後です。しかし 5 件は互いに無関係なので、本当は全部いっぺんに始めてよいはずです。

書き方80 ミリ秒かかるものが 5 件のとき
for-of の中で await する400 ミリ秒
Promise.all でまとめて待つ80 ミリ秒

配列を渡して、配列を受け取る

Promise.all に Promise の配列を渡すと、全部そろってから結果の配列を返す 1 つの Promise が返ります。

JavaScript

const [photo, bio, skills] = await Promise.all([ fetchPhoto(), fetchBio(), fetchSkills() ]);

配列を作った時点で、3 つの処理はもう動き始めています。Promise.all は始める道具ではなく、始まっているものを待ち合わせる道具です。

結果の並びは、渡した配列の並びと同じです。早く終わったものが前に来ることはありません。3 つ目が最初に終わっても、結果の 3 番目に入ります。だから上のように分割代入で受け取れますし、元の配列と添字でつき合わせることもできます。

件数が決まっていない配列を相手にするときは map が使えます。

JavaScript

const icons = await Promise.all( skills.map(function (skill) { return fetchIcon(skill); }) );

skills.map(...) が返すのは Promise の配列で、値の配列ではありません。ここに await を書かずそのまま使うと、Promise 同士を足したり比べたりすることになり、[object Promise] のような文字列ができあがります。なお map に渡す関数は Promise をそのまま返せばよく、async と await を付ける必要はありません。待つのは Promise.all 側の仕事です。

空の配列を渡しても動きます。Promise.all([]) はすぐに空の配列で確定するので、0 件のときの分岐を別に書かなくて済みます。

1 つでも失敗すると、全部失敗する

渡した中の 1 つが失敗した瞬間、Promise.all はその理由で失敗します。残りの結果は捨てられ、待ってもくれません。全部そろわないと画面を作れない場面ではこの性格が正しく働きますが、取れたぶんだけ出したい場面には向きません。

もう 1 つ知っておきたいのが、失敗しても残りの処理は止まらないという点です。取り消す仕組みは入っていません。

JavaScript

const results = await Promise.all([ fetchPhoto(), // 80 ミリ秒後に成功する fetchMissing() // 10 ミリ秒後に失敗する ]);

10 ミリ秒後に Promise.all は失敗しますが、1 つ目は 80 ミリ秒後にきちんと成功します。その結果を受け取る人がいないだけです。Promise.all を使った時点で、全か無かを選んでいる、と覚えてください。

よくある間違い

  • 配列に入れる前に await してしまう — 下の書き方だと、配列に入るのは Promise ではなく値です。Promise.all に渡すころにはすべて終わっていて、同時に動かした意味がありません

JavaScript

const promises = []; for (const skill of skills) { promises.push(await fetchIcon(skill)); // ここで待ってしまう } const icons = await Promise.all(promises);
  • 配列にせず、引数を並べて渡す — 引数は 1 つだけで、そこに配列を渡します。Promise.all(a, b) と書くと 2 つ目は無視され、結果が 1 件ぶんしか返りません。かっこの位置を見直してください

要件

  1. fetchViews(work) を作る。80 ミリ秒後に work.views を resolve する Promise を返す
  2. loadTotalViews(works) を async function として作り、map で作った Promise の配列を Promise.all に渡す
  3. await した結果から、count に件数、total に表示回数の合計を入れたオブジェクトを返す
  4. 空の配列を渡されたときは count も total も 0 にする

入出力例

loadTotalViews([{"id":1,"published":true,"title":"プロフィールサイト","views":120,"year":2026},{"id":2,"published":true,"title":"自己紹介カード","views":48,"year":2026},{"id":3,"published":true,"title":"スキル一覧の表","views":32,"year":2026},{"id":4,"published":true,"title":"作品ギャラリー","views":76,"year":2026},{"id":5,"published":false,"title":"学習ログ","views":0,"year":2025}]) → {"count":5,"total":276} loadTotalViews([]) → {"count":0,"total":0} loadTotalViews([{"id":5,"published":false,"title":"学習ログ","views":0,"year":2025}]) → {"count":1,"total":0} loadTotalViews([{"id":1,"published":true,"title":"プロフィールサイト","views":120,"year":2026},{"id":2,"published":true,"title":"自己紹介カード","views":48,"year":2026}]) → {"count":2,"total":168}

ヒント

works.map(...) が返すのは値の配列ではなく Promise の配列です。そのまま Promise.all に渡してください

Promise.all の引数は 1 つだけです。かっこの中に配列を 1 つ書きます

合計は第2章の reduce が使えます。初期値に 0 を渡しておくと、空の配列でも 0 が返ります

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/03/27·更新 2026/08/26

関連レッスン

  • 非同期のエラーを捕まえる

    reject された Promise は await した行で例外になります。第6章の try と catch をそのまま使って受け止め、失敗しても同じ形の値を返します。

  • つくる 読み込み中の表示を出す

    300 ミリ秒遅れて届く Promise を自作し、待っているあいだのスピナーと、届いたあとのカード表示を切り替えます。第9章で通信につなぐ前の下ごしらえです。

  • 第1章まとめクイズ

    Promise の確定、await の書き忘れ、forEach の中の await、Promise.all の並び順、reject の受け止め方を、コードを読んで確かめます。

  • HTTP と REST の読みかた

    ブラウザとサーバーが 1 往復でやりとりする HTTP の形と、URL の付けかたをそろえる REST の考えかたを読み解きます。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • Promise非同期の結果を表すラッパーオブジェクト
  • 配列サイズ固定の同型データの集まり
  • 処理計算や代入を表す長方形
  • 関数処理に名前を付けて再利用できる単位
  • 引数位置引数=順番で渡す。
  • Promise.all複数の Promise を並列に待つ API
  • オブジェクトキーと値のペアで構造を作るデータ
main.js
学習モード
エディタを読み込んでいます

メモ

Promise.all で同時に待つ

⌘S で保存