非同期処理とは?
JavaScriptにおける非同期処理とは、時間のかかる処理(例えば、サーバーからのデータ取得やファイルの読み込み)を待たずに、他の処理を並行して実行する仕組みです。これにより、ユーザーインターフェースの応答性を維持しながら、バックグラウンドでデータの取得や計算を行うことが可能になります。
非同期処理を実現するための主な手法として、Promiseとasync/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版」「非同期×バリデーション」「ローディングアニメーションとの組み合わせ」など💡