JavaScriptは、ウェブ開発において非常に強力なプログラミング言語です。その中でも、非同期処理を扱うための機能としてPromiseが広く利用されています。Promiseは、非同期操作が完了した後に結果を提供するオブジェクトであり、複雑なコールバック地獄を避けるために役立ちます。本記事では、Promiseの基本概念から始め、実際のデータ取得と操作方法、エラーハンドリング、そして複数の非同期処理の管理方法までを詳しく解説します。これにより、JavaScriptの非同期処理を効率的に管理し、信頼性の高いコードを書くための知識を習得できるでしょう。
Promiseの基本概念
Promiseは、JavaScriptにおける非同期処理を扱うためのオブジェクトであり、将来完了する可能性のある処理を表します。Promiseは以下の3つの状態を持ちます:
待機(Pending)
Promiseが生成された直後の状態で、まだ処理が完了していない状態です。この状態では、結果もエラーも発生していません。
成功(Fulfilled)
非同期処理が成功した状態です。このとき、Promiseは成功の結果(resolved value)を持ちます。
失敗(Rejected)
非同期処理が失敗した状態です。このとき、Promiseは失敗の理由(error)を持ちます。
Promiseを使用することで、非同期処理の結果を簡単に扱うことができ、エラーハンドリングや連鎖的な処理も容易になります。以下は、Promiseの基本的な使い方の例です:
let promise = new Promise((resolve, reject) => {
// 非同期処理を実行
let success = true; // 成功した場合
if (success) {
resolve("データ取得成功");
} else {
reject("データ取得失敗");
}
});
promise
.then(result => {
console.log(result); // "データ取得成功"が出力される
})
.catch(error => {
console.log(error); // エラーメッセージが出力される
});
このように、Promiseを使うことで、非同期処理の結果を明確に管理することができます。次に、非同期処理の必要性について説明します。
非同期処理の必要性
現代のウェブアプリケーションでは、ユーザーインターフェースが迅速に応答し、バックエンドと連携してデータを取得・操作することが求められます。非同期処理は、このような要求を満たすために不可欠です。ここでは、非同期処理の主な利点について説明します。
ユーザー体験の向上
非同期処理を使用することで、長時間かかる操作(例えば、サーバーからのデータ取得やファイルの読み込み)を行っている間も、ユーザーインターフェースを操作可能に保つことができます。これにより、ユーザーはアプリケーションの応答性を高く評価し、より快適に利用できます。
効率的なリソース利用
非同期処理は、リソースを効率的に利用するための手段でもあります。例えば、ウェブアプリケーションがサーバーからデータを取得している間、その間に他の操作を実行できるため、CPUやネットワークリソースを無駄にすることなく活用できます。
パフォーマンスの向上
非同期処理を適切に利用することで、アプリケーションの全体的なパフォーマンスが向上します。例えば、大量のデータを扱う操作を非同期で行うことで、メインスレッドの負荷を軽減し、スムーズな動作を実現できます。
具体例:APIからのデータ取得
APIからデータを取得する際、同期的に処理を行うと、ネットワークの遅延やサーバーの応答待ちの間、アプリケーション全体が停止してしまいます。非同期処理を使用することで、このような遅延を回避し、他の操作を並行して実行できます。
以下に、非同期処理を使用してAPIからデータを取得する例を示します。
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => response.json())
.then(data => resolve(data))
.catch(error => reject(error));
});
}
fetchData('https://api.example.com/data')
.then(data => {
console.log('データ取得成功:', data);
})
.catch(error => {
console.error('データ取得失敗:', error);
});
このように、非同期処理は現代のウェブ開発において不可欠な技術です。次に、Promiseの作成方法について詳しく説明します。
Promiseの作成方法
Promiseは、JavaScriptにおける非同期処理を管理するための強力なツールです。ここでは、Promiseの基本的な作成方法とその使用方法について具体的なコード例を交えて解説します。
Promiseの基本構造
Promiseは、非同期処理を行う関数をラップすることで作成されます。この関数は、resolve
とreject
という2つのコールバック関数を引数に取ります。resolve
は非同期処理が成功した場合に呼び出され、reject
は失敗した場合に呼び出されます。
以下は、Promiseの基本的な作成方法の例です:
let promise = new Promise((resolve, reject) => {
// 非同期処理を実行
let success = true; // 成功した場合
if (success) {
resolve("データ取得成功");
} else {
reject("データ取得失敗");
}
});
promise
.then(result => {
console.log(result); // "データ取得成功"が出力される
})
.catch(error => {
console.log(error); // "データ取得失敗"が出力される
});
非同期処理をPromiseでラップする
非同期処理をPromiseでラップすることで、その結果を簡単に管理できます。以下は、非同期操作であるsetTimeout
をPromiseでラップした例です:
function delay(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`遅延 ${ms} ミリ秒`);
}, ms);
});
}
delay(1000).then(message => {
console.log(message); // 1秒後に"遅延 1000 ミリ秒"が出力される
});
この例では、delay
関数が指定された時間(ミリ秒)だけ遅延した後に解決されるPromiseを返します。
Promiseを使ったAPIのデータ取得
実際にAPIからデータを取得する際にもPromiseが役立ちます。以下に、fetch
APIを使ってデータを取得する例を示します:
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
reject('ネットワーク応答エラー');
}
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
fetchData('https://api.example.com/data')
.then(data => {
console.log('データ取得成功:', data);
})
.catch(error => {
console.error('データ取得失敗:', error);
});
この例では、指定されたURLからデータを取得し、成功した場合はデータを、失敗した場合はエラーメッセージを出力します。
Promiseを利用することで、非同期処理の結果を明確に管理でき、コードの可読性と保守性が向上します。次に、Promiseのチェーン処理に使用するthen
とcatch
の使い方について説明します。
thenとcatchの使い方
Promiseを使用すると、非同期処理の結果を簡単に処理することができます。then
とcatch
は、Promiseの結果を連鎖的に処理するためのメソッドです。ここでは、それぞれの使い方を具体例と共に説明します。
thenの使い方
then
メソッドは、Promiseが成功した(fulfilled)ときに呼び出される関数を指定します。この関数は、Promiseが解決した結果を引数として受け取ります。さらに、then
は新しいPromiseを返すため、連鎖的に複数の非同期処理を行うことができます。
以下は、then
メソッドを使用した基本的な例です:
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("データ取得成功"), 1000);
});
promise
.then(result => {
console.log(result); // "データ取得成功"が出力される
return result + " - 処理完了";
})
.then(result => {
console.log(result); // "データ取得成功 - 処理完了"が出力される
});
この例では、最初のthen
でデータ取得の成功メッセージを出力し、次のthen
でその結果に追加のメッセージを付加して出力しています。
catchの使い方
catch
メソッドは、Promiseが失敗した(rejected)ときに呼び出される関数を指定します。この関数は、Promiseが拒否された理由(エラー)を引数として受け取ります。catch
は、エラーハンドリングをシンプルにするために使用されます。
以下は、catch
メソッドを使用した基本的な例です:
let promise = new Promise((resolve, reject) => {
setTimeout(() => reject("データ取得失敗"), 1000);
});
promise
.then(result => {
console.log(result); // この行は実行されない
})
.catch(error => {
console.error(error); // "データ取得失敗"が出力される
});
この例では、Promiseが拒否されるとcatch
メソッドが呼び出され、エラーメッセージを出力します。
thenとcatchの組み合わせ
then
とcatch
を組み合わせることで、非同期処理の成功と失敗を適切に処理することができます。以下に、fetch
を使ってデータを取得する例を示します:
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
reject('ネットワーク応答エラー');
}
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
fetchData('https://api.example.com/data')
.then(data => {
console.log('データ取得成功:', data);
})
.catch(error => {
console.error('データ取得失敗:', error);
});
この例では、then
とcatch
を連鎖させることで、データの取得成功時と失敗時の処理を明確に分けて管理しています。
Promiseを使用することで、非同期処理の流れを整理し、エラーハンドリングを一貫して行うことができます。次に、Promiseをより簡単に扱うためのasync/await
構文について説明します。
async/awaitの導入
Promiseを使った非同期処理は非常に便利ですが、複雑なチェーンが増えるとコードの可読性が低下することがあります。async/await
は、Promiseをより簡潔に扱うための構文で、非同期処理を同期的なコードのように書くことができます。ここでは、async/await
の基本的な使い方を説明します。
async関数
async
キーワードを使って関数を定義すると、その関数は常にPromiseを返します。この関数の内部でawait
キーワードを使うことで、Promiseの完了を待つことができます。
以下は、基本的なasync
関数の例です:
async function fetchData() {
return "データ取得成功";
}
fetchData().then(result => {
console.log(result); // "データ取得成功"が出力される
});
この例では、fetchData
関数は即座に成功したPromiseを返し、その結果がthen
で処理されます。
awaitキーワード
await
キーワードは、Promiseの完了を待つために使用されます。await
は、async
関数の中でのみ使用できます。await
はPromiseが解決されるまで関数の実行を一時停止し、Promiseの結果を返します。
以下は、await
を使って非同期データを取得する例です:
async function fetchData() {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
return data;
}
fetchData()
.then(data => {
console.log('データ取得成功:', data);
})
.catch(error => {
console.error('データ取得失敗:', error);
});
この例では、fetch
関数とresponse.json
関数の両方がPromiseを返すため、それぞれにawait
を使って非同期処理の完了を待っています。
エラーハンドリング
async/await
を使ったエラーハンドリングは、通常の同期コードと同様にtry
/catch
ブロックを使用して行います。これにより、非同期処理のエラーも簡単に処理できます。
以下は、try
/catch
を使ったエラーハンドリングの例です:
async function fetchData() {
try {
let response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
return data;
} catch (error) {
console.error('データ取得失敗:', error);
throw error;
}
}
fetchData()
.then(data => {
console.log('データ取得成功:', data);
})
.catch(error => {
console.error('データ取得失敗:', error);
});
この例では、try
ブロック内でawait
を使って非同期処理を行い、エラーが発生した場合はcatch
ブロックで処理しています。これにより、エラーが発生しても一貫した方法でハンドリングできます。
async/await
を使うことで、非同期処理がより直感的で読みやすくなります。次に、実際のデータ取得例を使って、非同期処理の流れをさらに詳しく見ていきます。
データの取得例
非同期処理の基本を理解したところで、実際にAPIからデータを取得する具体的な例を見てみましょう。このセクションでは、fetch
APIとasync/await
を使用して、外部のAPIからデータを取得し、そのデータをコンソールに表示する方法を解説します。
APIからのデータ取得
まずは、fetch
を使って外部のAPIからデータを取得し、取得したデータをコンソールに表示する例を示します。
async function getData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
console.log('データ取得成功:', data);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
getData();
この例では、以下の手順でデータを取得しています:
fetch
関数を使って指定されたURLにリクエストを送信します。await
を使ってリクエストの完了を待ちます。- レスポンスが正常でない場合、エラーをスローします。
- 正常なレスポンスの場合、
response.json()
を使ってレスポンスボディをJSON形式に変換します。 - 取得したデータをコンソールに表示します。
実際の使用例
実際のウェブアプリケーションでは、APIから取得したデータを画面に表示することが一般的です。以下の例では、取得したデータをHTMLに挿入して表示する方法を示します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>データ取得例</title>
</head>
<body>
<div id="data"></div>
<script>
async function getData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
document.getElementById('data').innerText = JSON.stringify(data, null, 2);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
getData();
</script>
</body>
</html>
この例では、次の手順を行います:
fetch
関数を使ってAPIからデータを取得します。- データをJSON形式に変換します。
- 取得したデータをHTMLの
<div>
要素に挿入して表示します。
これにより、ウェブページ上にAPIから取得したデータが表示されます。
非同期処理を用いたデータ取得の基本的な例を見てきました。次に、取得したデータをどのように操作・加工するかについて説明します。
データの操作方法
取得したデータをそのまま表示するだけでなく、実際にはさまざまな方法で操作・加工する必要があります。このセクションでは、取得したデータを操作する具体的な方法について説明します。
データのフィルタリング
データを取得した後、そのデータを特定の条件に基づいてフィルタリングすることがよくあります。以下は、取得したデータをフィルタリングする例です。
async function fetchAndFilterData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
// ユーザーIDが1の投稿だけをフィルタリング
let filteredData = data.filter(post => post.userId === 1);
console.log('フィルタリング後のデータ:', filteredData);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchAndFilterData();
この例では、APIから取得したすべての投稿データの中から、userId
が1の投稿だけをフィルタリングしています。
データのマッピング
データのマッピングは、データセットの各要素を別の形式に変換するために使用されます。以下は、取得したデータをマッピングする例です。
async function fetchAndMapData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
// タイトルだけを抽出した新しい配列を作成
let titles = data.map(post => post.title);
console.log('タイトルのリスト:', titles);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchAndMapData();
この例では、すべての投稿データからtitle
プロパティだけを抽出し、新しい配列を作成しています。
データの集計
データを集計して統計情報を取得することも一般的です。以下は、取得したデータを集計する例です。
async function fetchAndAggregateData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
// ユーザーごとの投稿数を集計
let postCounts = data.reduce((acc, post) => {
acc[post.userId] = (acc[post.userId] || 0) + 1;
return acc;
}, {});
console.log('ユーザーごとの投稿数:', postCounts);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchAndAggregateData();
この例では、各ユーザーが投稿した記事の数を集計しています。
データの操作を画面に反映
最後に、操作したデータをHTMLに反映する方法を示します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>データ操作例</title>
</head>
<body>
<ul id="titles"></ul>
<script>
async function fetchAndDisplayTitles() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
// タイトルだけを抽出した新しい配列を作成
let titles = data.map(post => post.title);
// HTMLに反映
let ul = document.getElementById('titles');
titles.forEach(title => {
let li = document.createElement('li');
li.textContent = title;
ul.appendChild(li);
});
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchAndDisplayTitles();
</script>
</body>
</html>
この例では、取得したデータからタイトルだけを抽出し、HTMLのリストとして表示しています。
データのフィルタリング、マッピング、集計などの操作を行うことで、取得したデータをより有用に活用することができます。次に、Promiseにおけるエラーハンドリングのベストプラクティスについて説明します。
エラーハンドリング
Promiseを使用する際、エラーハンドリングは非常に重要です。適切なエラーハンドリングを行うことで、非同期処理の失敗時に適切な対策を講じることができます。このセクションでは、Promiseにおけるエラーハンドリングのベストプラクティスについて説明します。
基本的なエラーハンドリング
Promiseのエラーハンドリングは、catch
メソッドを使用して行います。catch
メソッドは、Promiseが拒否された場合に呼び出される関数を指定します。
以下は、基本的なエラーハンドリングの例です:
let promise = new Promise((resolve, reject) => {
let success = false; // 成功しない場合
if (success) {
resolve("データ取得成功");
} else {
reject("データ取得失敗");
}
});
promise
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error); // "データ取得失敗"が出力される
});
この例では、Promiseが拒否された場合、catch
メソッドでエラーメッセージを出力します。
非同期関数でのエラーハンドリング
async
/await
構文を使用する場合、エラーハンドリングはtry
/catch
ブロックを使用して行います。これにより、同期的なコードのようにエラーを扱うことができます。
以下は、async
関数内でのエラーハンドリングの例です:
async function fetchData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
console.log('データ取得成功:', data);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchData();
この例では、try
ブロック内で非同期処理を行い、エラーが発生した場合はcatch
ブロックで処理します。
具体的なエラーメッセージの提供
エラーが発生した場合、具体的なエラーメッセージを提供することが重要です。これにより、問題の原因を迅速に特定し、対策を講じることができます。
async function fetchData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error(`HTTPエラー: ${response.status}`);
}
let data = await response.json();
console.log('データ取得成功:', data);
} catch (error) {
console.error('データ取得失敗:', error.message);
}
}
fetchData();
この例では、HTTPステータスコードを含む具体的なエラーメッセージを提供しています。
エラーハンドリングのベストプラクティス
- 一貫性のあるエラーハンドリング:
非同期処理のエラーハンドリングを一貫して行い、全てのPromiseで適切にエラーを処理することが重要です。 - エラーログの記録:
エラーが発生した場合、その詳細をログとして記録することで、後で問題を調査・修正しやすくなります。 - ユーザーフィードバック:
エラーが発生した場合、ユーザーに適切なフィードバックを提供し、次に取るべきアクションを示すことが重要です。
以下は、ユーザーにエラーメッセージを表示する例です:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>エラーハンドリング例</title>
</head>
<body>
<div id="data"></div>
<div id="error" style="color: red;"></div>
<script>
async function fetchData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
document.getElementById('data').innerText = JSON.stringify(data, null, 2);
} catch (error) {
console.error('データ取得失敗:', error);
document.getElementById('error').innerText = `エラー: ${error.message}`;
}
}
fetchData();
</script>
</body>
</html>
この例では、エラーが発生した場合にエラーメッセージをHTMLに表示しています。
Promiseを使用した非同期処理において、適切なエラーハンドリングを行うことは、信頼性の高いアプリケーションを構築するために不可欠です。次に、複数の非同期処理を同時に管理する方法について説明します。
応用例:複数の非同期処理の管理
現代のウェブアプリケーションでは、複数の非同期処理を同時に扱う必要がある場合がよくあります。Promiseを使用すると、これらの非同期処理を効率的に管理することができます。このセクションでは、複数のPromiseを同時に処理する方法と、その実例について説明します。
Promise.all
Promise.all
は、複数のPromiseを並行して実行し、すべてのPromiseが解決されたときに一つのPromiseを返します。いずれかのPromiseが拒否された場合、Promise.all
も拒否されます。
以下は、Promise.all
を使用した例です:
async function fetchMultipleData() {
try {
let [post1, post2, post3] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/posts/1').then(response => response.json()),
fetch('https://jsonplaceholder.typicode.com/posts/2').then(response => response.json()),
fetch('https://jsonplaceholder.typicode.com/posts/3').then(response => response.json())
]);
console.log('Post 1:', post1);
console.log('Post 2:', post2);
console.log('Post 3:', post3);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchMultipleData();
この例では、3つの異なるAPIリクエストを並行して実行し、すべてのリクエストが完了した後にそれぞれの結果を出力します。
Promise.race
Promise.race
は、複数のPromiseのうち最初に完了したものを返します。これは、最も早く完了するPromiseの結果に応じて処理を行いたい場合に便利です。
以下は、Promise.race
を使用した例です:
async function fetchFirstData() {
try {
let result = await Promise.race([
fetch('https://jsonplaceholder.typicode.com/posts/1').then(response => response.json()),
fetch('https://jsonplaceholder.typicode.com/posts/2').then(response => response.json())
]);
console.log('最初に取得されたデータ:', result);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchFirstData();
この例では、2つのAPIリクエストのうち、先に完了した方の結果を出力します。
実際の応用例:複数のAPIからのデータ取得と統合
実際のウェブアプリケーションでは、複数のAPIからデータを取得し、そのデータを統合する必要がある場合があります。以下は、複数のAPIからデータを取得して統合する具体例です:
async function fetchAndCombineData() {
try {
let [users, posts] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/users').then(response => response.json()),
fetch('https://jsonplaceholder.typicode.com/posts').then(response => response.json())
]);
// ユーザーごとの投稿数を集計
let userPostsCount = users.map(user => {
let userPosts = posts.filter(post => post.userId === user.id);
return {
userId: user.id,
userName: user.name,
postCount: userPosts.length
};
});
console.log('ユーザーごとの投稿数:', userPostsCount);
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchAndCombineData();
この例では、ユーザー情報と投稿情報をそれぞれ別のAPIから取得し、ユーザーごとの投稿数を集計しています。
HTMLへのデータ表示
最後に、取得したデータをHTMLに表示する方法を示します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>複数の非同期処理例</title>
</head>
<body>
<ul id="userPostsCount"></ul>
<script>
async function fetchAndDisplayData() {
try {
let [users, posts] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/users').then(response => response.json()),
fetch('https://jsonplaceholder.typicode.com/posts').then(response => response.json())
]);
let userPostsCount = users.map(user => {
let userPosts = posts.filter(post => post.userId === user.id);
return {
userId: user.id,
userName: user.name,
postCount: userPosts.length
};
});
let ul = document.getElementById('userPostsCount');
userPostsCount.forEach(user => {
let li = document.createElement('li');
li.textContent = `${user.userName}: ${user.postCount} posts`;
ul.appendChild(li);
});
} catch (error) {
console.error('データ取得失敗:', error);
}
}
fetchAndDisplayData();
</script>
</body>
</html>
この例では、複数のAPIからデータを取得し、ユーザーごとの投稿数をHTMLリストに表示しています。
複数の非同期処理を効率的に管理することで、複雑なデータ処理を簡単に行うことができます。次に、学んだ内容を定着させるための演習問題を提供します。
演習問題
ここでは、Promiseとasync/await
を使った非同期処理の基本を理解するための演習問題を提供します。これらの演習を通じて、非同期処理の使い方とエラーハンドリングの方法を実践的に学びましょう。
演習1:Promiseを使った非同期処理
次の条件に従って、Promiseを使って非同期処理を実装してください。
条件:
fetchUserData
関数を作成し、指定されたURLからユーザーデータを取得する。- データ取得が成功した場合、取得したデータをコンソールに表示する。
- データ取得が失敗した場合、エラーメッセージをコンソールに表示する。
コードテンプレート:
function fetchUserData(url) {
// ここにPromiseを使った非同期処理を実装
}
fetchUserData('https://jsonplaceholder.typicode.com/users/1');
解答例:
function fetchUserData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
reject('ネットワーク応答エラー');
}
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
fetchUserData('https://jsonplaceholder.typicode.com/users/1')
.then(data => {
console.log('ユーザーデータ取得成功:', data);
})
.catch(error => {
console.error('ユーザーデータ取得失敗:', error);
});
演習2:async/awaitを使った非同期処理
次の条件に従って、async/await
を使って非同期処理を実装してください。
条件:
fetchUserDataAsync
というasync
関数を作成し、指定されたURLからユーザーデータを取得する。- データ取得が成功した場合、取得したデータをコンソールに表示する。
- データ取得が失敗した場合、エラーメッセージをコンソールに表示する。
コードテンプレート:
async function fetchUserDataAsync(url) {
// ここにasync/awaitを使った非同期処理を実装
}
fetchUserDataAsync('https://jsonplaceholder.typicode.com/users/1');
解答例:
async function fetchUserDataAsync(url) {
try {
let response = await fetch(url);
if (!response.ok) {
throw new Error('ネットワーク応答エラー');
}
let data = await response.json();
console.log('ユーザーデータ取得成功:', data);
} catch (error) {
console.error('ユーザーデータ取得失敗:', error);
}
}
fetchUserDataAsync('https://jsonplaceholder.typicode.com/users/1');
演習3:複数の非同期処理の管理
次の条件に従って、複数の非同期処理を同時に実行し、結果を統合してください。
条件:
fetchMultipleUserData
というasync
関数を作成し、複数のユーザーデータを同時に取得する。- 取得したデータを配列に格納し、コンソールに表示する。
- いずれかのデータ取得が失敗した場合、エラーメッセージをコンソールに表示する。
コードテンプレート:
async function fetchMultipleUserData() {
// ここに複数の非同期処理を管理するコードを実装
}
fetchMultipleUserData();
解答例:
async function fetchMultipleUserData() {
try {
let urls = [
'https://jsonplaceholder.typicode.com/users/1',
'https://jsonplaceholder.typicode.com/users/2',
'https://jsonplaceholder.typicode.com/users/3'
];
let promises = urls.map(url => fetch(url).then(response => response.json()));
let users = await Promise.all(promises);
console.log('複数ユーザーデータ取得成功:', users);
} catch (error) {
console.error('複数ユーザーデータ取得失敗:', error);
}
}
fetchMultipleUserData();
これらの演習を通じて、Promiseとasync/await
を使った非同期処理の基本を実践的に学ぶことができます。次に、本記事のまとめを行います。
まとめ
本記事では、JavaScriptにおけるPromiseを使った非同期処理の基本と応用について解説しました。まず、Promiseの基本概念と構造について説明し、非同期処理の必要性とその利点を具体例を交えて紹介しました。続いて、Promiseの作成方法、then
とcatch
を使ったチェーン処理、さらにasync/await
構文を用いた非同期処理の簡便な記述方法について学びました。
また、実際のデータ取得例を通じて、APIからデータを取得し、それを操作・加工する方法を詳しく説明しました。エラーハンドリングのベストプラクティスを紹介し、適切なエラーメッセージの提供やログの記録、ユーザーへのフィードバックの重要性についても触れました。最後に、複数の非同期処理を同時に管理する方法をPromise.all
やPromise.race
を使った実例と共に示し、学んだ内容を実践的に適用するための演習問題を提供しました。
これらの知識を活用することで、JavaScriptの非同期処理を効率的に管理し、信頼性の高いアプリケーションを開発することができるようになるでしょう。非同期処理は現代のウェブ開発において不可欠な技術であり、今回学んだ内容を実際のプロジェクトで積極的に活用してみてください。
コメント