JavaScriptの非同期処理とPromise

概要

JavaScriptにおける非同期処理は、同時に複数の操作を効率的に行うために重要です。この章では、非同期処理の基本と、Promiseを使用した非同期処理の方法について学びます。

目次

  1. 非同期処理の基本
  2. Promiseの基本
  3. Promiseのチェーン
  4. エラー処理
  5. asyncawait
  6. 非同期処理のベストプラクティス

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. asyncawait

async関数は、非同期処理をより簡潔に書くための方法です。awaitを使ってPromiseの解決を待ちます。

async function asyncFunction() {
  const message = await myPromise;
  console.log(message); // "非同期処理成功"
}

await asyncFunction();
console.log("非同期処理完了後")
// 下記の順に出力される
// "非同期処理成功"
// "非同期処理完了後"

6. 非同期処理のベストプラクティス

  • 非同期処理を正確に理解し、適切に使用する。
  • Promiseチェーンを清潔に保ち、ネストを避ける。
  • エラー処理を適切に行う。



練習問題

  1. 外部APIからデータを取得する非同期関数をPromisethen, catchを使用して作成してください。
  2. 同じ関数をasync/awaittry catchを使用して作成してください。

解答例: 天気情報を取得するアプリケーション

この例では、外部の天気予報API(例: OpenWeatherMap)を使用して、特定の都市の天気予報を取得し、結果を表示します。

1. Promisethen, 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/awaittry 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キーを取得する必要があります。
  • エラーハンドリング: fetchresponse.okをチェックして、応答が成功したかどうかを判断します。これにより、APIからのエラー応答も適切に処理できます。
  • 非同期処理: fetchは非同期操作を行います。thencatch、またはasync/awaitを使用して、これらの操作が完了するのを待ち、結果を取得します。