JavaScript 非同期処理の練習問題10選|fetchとasync/awaitで学ぶ基礎と実践


非同期処理とは?

JavaScriptにおける非同期処理とは、時間のかかる処理(例えば、サーバーからのデータ取得やファイルの読み込み)を待たずに、他の処理を並行して実行する仕組みです。​これにより、ユーザーインターフェースの応答性を維持しながら、バックグラウンドでデータの取得や計算を行うことが可能になります。​

非同期処理を実現するための主な手法として、Promiseasync/awaitがあります。​これらを理解し適切に使いこなすことで、効率的で読みやすいコードを書くことができます。


本記事の内容について

本記事では、JavaScriptの非同期処理に関する練習問題を10問ご用意しました。​各問題には、HTML構造とscript.jsに分けた解答例を掲載しています。​実際に手を動かしながら学ぶことで、非同期処理の理解を深めていきましょう。


練習問題①:fetchでAPIからデータ取得(Promise)

ボタンをクリックすると、JSONPlaceholderのAPIからデータを取得し、タイトルをアラート表示します。

HTML:

<button id="btn1">データ取得(then)</button>
JavaScript解答
document.getElementById('btn1').addEventListener('click', () => {
  fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => response.json())
    .then(data => {
      alert('タイトル: ' + data.title);
    })
    .catch(error => {
      alert('エラーが発生しました');
    });
});

練習問題①:fetchでAPIからデータ取得(Promise)

ボタンをクリックすると、JSONPlaceholderのAPIからデータを取得し、タイトルをアラート表示します。

HTML:

<button id="btn1">データ取得(then)</button>
JavaScript解答
document.getElementById('btn1').addEventListener('click', () => {
  fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => response.json())
    .then(data => {
      alert('タイトル: ' + data.title);
    })
    .catch(error => {
      alert('エラーが発生しました');
    });
});

練習問題②:async/awaitでAPI取得

上記の問題を、async/awaitを使用して書き換えます。

HTML:

<button id="btn2">データ取得(async/await)</button>
JavaScript解答
document.getElementById('btn2').addEventListener('click', async () => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    const data = await response.json();
    alert('タイトル: ' + data.title);
  } catch (error) {
    alert('エラーが発生しました');
  }
});

練習問題③:ネットワークエラーをハンドリング

存在しないURLにリクエストを送り、エラーをキャッチして適切に処理します。

HTML:

<button id="btn3">エラーテスト</button>
JavaScript解答
document.getElementById('btn3').addEventListener('click', () => {
  fetch('https://jsonplaceholder.typicode.com/invalid-url')
    .then(response => {
      if (!response.ok) {
        throw new Error('レスポンスエラー');
      }
      return response.json();
    })
    .then(data => console.log(data))
    .catch(error => {
      alert('エラー: ' + error.message);
    });
});

練習問題④:複数のAPIを順番に取得する

2つのAPIから順番にデータを取得し、それぞれのタイトルを表示します。

HTML:

<button id="btn4">2件取得(順番)</button>
JavaScript解答
document.getElementById('btn4').addEventListener('click', async () => {
  try {
    const response1 = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    const data1 = await response1.json();

    const response2 = await fetch('https://jsonplaceholder.typicode.com/todos/2');
    const data2 = await response2.json();

    alert(`1: ${data1.title}\n2: ${data2.title}`);
  } catch (error) {
    alert('取得失敗');
  }
});

練習問題⑤:Promise.allで同時に取得

複数のAPIを並列で実行し、すべての結果を表示します。

HTML:

<button id="btn5">2件取得(同時)</button>
JavaScript解答
document.getElementById('btn5').addEventListener('click', async () => {
  try {
    const [response1, response2] = await Promise.all([
      fetch('https://jsonplaceholder.typicode.com/todos/1'),
      fetch('https://jsonplaceholder.typicode.com/todos/2')
    ]);

    const data1 = await response1.json();
    const data2 = await response2.json();

    alert(`1: ${data1.title}\n2: ${data2.title}`);
  } catch (error) {
    alert('取得エラー');
  }
});

練習問題⑥:setTimeoutで遅延表示

ボタンをクリックしてから3秒後に「こんにちは」と表示されるようにします。​

HTML:

<button id="btn6">3秒後に表示</button>
<p id="msg6"></p>
JavaScript解答
document.getElementById('btn6').addEventListener('click', () => {
  document.getElementById('msg6').textContent = '3秒待ってください...';

  setTimeout(() => {
    document.getElementById('msg6').textContent = 'こんにちは!';
  }, 3000);
});

練習問題⑦:ローディング表示 → API取得後に表示

ボタンをクリックすると「読み込み中…」と表示され、取得完了後にタイトルを表示します。

HTML:

<button id="btn7">データを取得</button>
<p id="result7"></p>
JavaScript解答
document.getElementById('btn7').addEventListener('click', async () => {
  const result = document.getElementById('result7');
  result.textContent = '読み込み中...';

  try {
    const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    const data = await res.json();
    result.textContent = '取得したタイトル:' + data.title;
  } catch (e) {
    result.textContent = 'エラーが発生しました';
  }
});

練習問題⑧:ボタン連打を防ぐ(多重実行対策)

通信中はボタンを無効化し、完了後に再度有効化します。

HTML:

<button id="btn8">送信する</button>
<p id="status8"></p>
JavaScript解答
const btn8 = document.getElementById('btn8');
const status8 = document.getElementById('status8');

btn8.addEventListener('click', async () => {
  btn8.disabled = true;
  status8.textContent = '送信中...';

  await new Promise(resolve => setTimeout(resolve, 2000)); // 疑似送信処理

  status8.textContent = '送信完了!';
  btn8.disabled = false;
});

練習問題⑨:データをPOST送信して結果を表示

名前を入力して送信ボタンを押すと、APIにPOSTし「送信完了」メッセージを表示します。

HTML:

<input type="text" id="nameInput9" placeholder="名前を入力" />
<button id="btn9">送信</button>
<p id="status9"></p>
JavaScript解答
document.getElementById('btn9').addEventListener('click', async () => {
  const name = document.getElementById('nameInput9').value;
  const status = document.getElementById('status9');

  status.textContent = '送信中...';

  try {
    await fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      body: JSON.stringify({ name }),
      headers: { 'Content-Type': 'application/json' }
    });

    status.textContent = `送信完了!こんにちは、${name}さん!`;
  } catch (e) {
    status.textContent = '送信に失敗しました';
  }
});

練習問題⑩:ユーザーID入力でAPIから情報を取得

ユーザーID(1〜10)を入力してそのユーザーの名前を取得し表示します。

HTML:

<input type="number" id="userIdInput10" placeholder="ユーザーID (1~10)" />
<button id="btn10">ユーザー取得</button>
<p id="userInfo10"></p>
JavaScript解答
document.getElementById('btn10').addEventListener('click', async () => {
  const id = document.getElementById('userIdInput10').value;
  const userInfo = document.getElementById('userInfo10');

  if (!id) {
    userInfo.textContent = 'IDを入力してください';
    return;
  }

  userInfo.textContent = '取得中...';

  try {
    const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
    if (!res.ok) throw new Error('取得失敗');
    const user = await res.json();
    userInfo.textContent = `名前:${user.name}`;
  } catch (e) {
    userInfo.textContent = '取得できませんでした';
  }
});

✅ まとめ

JavaScriptの非同期処理は、現代のWebアプリでは避けて通れない重要なスキルです。
今回の10問を通して、「非同期の書き方」だけでなく、「実際の使い方」や「ユーザー体験の向上」まで意識できるようになると、実務にも大いに活かせます。

次回は「axios版」「非同期×バリデーション」「ローディングアニメーションとの組み合わせ」など💡

✪ 画像素材がないものはランダムで表示されるようになっています。フリー素材などでご用意ください。

おすすめChromeプラグイン一覧

プラグイン名特徴
GoFullPageウェブページ全体のスクリーンショットを簡単に取得できるブラウザ拡張機能です。
ColorZilla色を抽出するための拡張機能です。
WhatFontウェブページ上のフォントの情報を簡単に確認できるブラウザ拡張機能です。
PerfectPixelデザイナーが作成したデザインと実際にコーディングされたウェブページがどの程度一致しているかを確認・調整するためのブラウザ拡張機能です。

模写の手順

ステップ内容
ステップ 1構図を手書きか全画面スクショ(Go full page等)した後、ペイントツールで四角で囲い、大まかなclass,命名規則をあらかじめ決める。
ステップ 2HTMLの基本構造を作成する
ステップ 3CSSでレイアウトを模写する
ステップ 4 中級〜JavaScriptを追加して動きを再現する
ステップ 5最終調整を行い、検証ツールやPerfectPixel(chromeプラグイン)などで完成を確認する。