JavaScriptの非同期処理とPromise
概要
JavaScriptにおける非同期処理は、同時に複数の操作を効率的に行うために重要です。この章では、非同期処理の基本と、Promiseを使用した非同期処理の方法について学びます。
目次
- 非同期処理の基本
- Promiseの基本
- Promiseのチェーン
- エラー処理
async
とawait
- 非同期処理のベストプラクティス
1. 非同期処理の基本
非同期処理は、ブロッキング操作(例えばデータの読み込み)を待機せずにプログラムの実行を続けることを可能にします。
console.log("1. 開始");
setTimeout(() => {
console.log("2. 非同期処理完了");
}, 2000);
console.log("3. 終了");
2. Promiseの基本
Promiseは非同期操作の最終的な完了(または失敗)およびその結果の値を表します。
基本構文
let myPromise = new Promise(function(resolve, reject) {
// 非同期処理
if (/* 成功 */) {
resolve("非同期処理成功");
} else { /* 失敗 */
reject("非同期処理失敗");
}
});
myPromise.then((message) => {
console.log(message); // "非同期処理成功" or "非同期処理失敗"
});
then
, catch
による処理
myPromise.then(
result => { /* 成功した場合の処理 */ },
error => { /* 失敗した場合の処理 */ }
);
// または
myPromise.then(result => { /* 成功した場合の処理 */ })
.catch(error => { /* 失敗した場合の処理 */ });
3. Promiseのチェーン
Promiseをチェーンすることで、複数の非同期処理を順序良く実行できます。
myPromise
.then((message) => {
console.log(message);
return "次の処理";
})
.then((nextMessage) => {
console.log(nextMessage);
});
4. エラー処理
catch
メソッドを使用して、Promiseチェーン内のエラーを捕捉できます。
myPromise
.then((message) => {
throw new Error("エラー発生"); // myPromiseが成功していてもここでcatchに移行する
})
.catch((error) => {
console.error(error.message);
});
async function myFunction() {
try {
let value = await myPromise; // 成功時の処理
} catch (error) {
// エラー処理
}
}
5. async
とawait
async
関数は、非同期処理をより簡潔に書くための方法です。await
を使ってPromiseの解決を待ちます。
async function asyncFunction() {
const message = await myPromise;
console.log(message); // "非同期処理成功"
}
await asyncFunction();
console.log("非同期処理完了後")
// 下記の順に出力される
// "非同期処理成功"
// "非同期処理完了後"
6. 非同期処理のベストプラクティス
- 非同期処理を正確に理解し、適切に使用する。
- Promiseチェーンを清潔に保ち、ネストを避ける。
- エラー処理を適切に行う。
練習問題
- 外部APIからデータを取得する非同期関数を
Promise
とthen
,catch
を使用して作成してください。 - 同じ関数を
async/await
とtry catch
を使用して作成してください。
解答例: 天気情報を取得するアプリケーション
この例では、外部の天気予報API(例: OpenWeatherMap)を使用して、特定の都市の天気予報を取得し、結果を表示します。
1. Promise
とthen
, catch
を使用する場合
function getWeather(city) {
let apiKey = 'あなたのAPIキー';
let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`;
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('天気情報の取得に失敗しました。');
}
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
getWeather('Tokyo').then(data => {
console.log(`東京の天気: ${data.weather[0].main}`);
}).catch(error => {
console.error(error);
});
2. async/await
とtry catch
を使用する場合
async function getWeather(city) {
let apiKey = 'あなたのAPIキー';
let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`;
try {
let response = await fetch(url);
if (!response.ok) {
throw new Error('天気情報の取得に失敗しました。');
}
let data = await response.json();
console.log(`東京の天気: ${data.weather[0].main}`);
} catch (error) {
console.error(error);
}
}
getWeather('Tokyo');
考慮点
- APIキー: 外部のAPIを使用する場合、APIキーが必要になることがあります。OpenWeatherMapなどのサービスでは、アカウントを作成してAPIキーを取得する必要があります。
- エラーハンドリング:
fetch
のresponse.ok
をチェックして、応答が成功したかどうかを判断します。これにより、APIからのエラー応答も適切に処理できます。 - 非同期処理:
fetch
は非同期操作を行います。then
とcatch
、またはasync/await
を使用して、これらの操作が完了するのを待ち、結果を取得します。