TypeScriptで非同期処理を書く|Promiseとasync/await

先生

TypeScriptで非同期処理?Promiseとasync/awaitを使いこなして、ワンランク上の開発者になろう!🚀

TypeScriptで非同期処理をマスター!Promiseとasync/await徹底解説

TypeScriptで非同期処理を扱う方法はいくつかありますが、最も一般的なのはPromiseとasync/awaitを使う方法です。これらの機能を理解することで、より効率的で読みやすいコードを書くことができます。この記事では、Promiseとasync/awaitの基本的な使い方から、エラーハンドリング、応用例までを分かりやすく解説します。

非同期処理は、時間のかかる処理(APIリクエスト、ファイル読み込みなど)をバックグラウンドで実行し、その間、他の処理をブロックしないようにする仕組みです。これにより、ユーザーインターフェースの応答性を維持し、快適なユーザーエクスペリエンスを提供できます。

TypeScriptはJavaScriptのスーパーセットであり、静的型付けなどの機能が追加されています。これにより、より安全で保守性の高いコードを書くことができます。非同期処理においても、TypeScriptの型システムを活用することで、エラーを早期に発見し、より堅牢なアプリケーションを構築できます。

Promiseとは?基本的な使い方と特徴

Promiseは、非同期処理の結果を表現するオブジェクトです。Promiseには、Pending(保留)、Fulfilled(成功)、Rejected(失敗)の3つの状態があります。

Promiseを作成するには、new Promise()コンストラクタを使用します。コンストラクタには、resolve関数とreject関数を引数として持つコールバック関数を渡します。

const promise = new Promise((resolve, reject) => {
  // 非同期処理
  setTimeout(() => {
    const data = 'Hello, Promise!';
    resolve(data); // 成功した場合
    // reject('Error occurred!'); // 失敗した場合
  }, 1000);
});

PromiseがFulfilled状態になると、then()メソッドで結果を受け取ることができます。Rejected状態になると、catch()メソッドでエラーを受け取ることができます。

promise
  .then(data => {
    console.log('Data:', data); // Data: Hello, Promise!
  })
  .catch(error => {
    console.error('Error:', error);
  });

async/awaitでさらに読みやすいコードへ

async/awaitは、Promiseをよりシンプルに記述するための構文です。asyncキーワードを関数に付与することで、その関数内でawaitキーワードを使用できるようになります。

awaitキーワードは、PromiseがFulfilled状態になるまで処理を一時停止し、結果を返します。これにより、非同期処理を同期処理のように記述することができます。

async function fetchData() {
  try {
    const data = await promise;
    console.log('Data:', data); // Data: Hello, Promise!
  } catch (error) {
    console.error('Error:', error);
  }
}
fetchData();

async/awaitを使用すると、Promiseチェーンを記述する必要がなくなり、コードがより読みやすく、保守しやすくなります。

try…catch構文を使用することで、async/awaitで発生したエラーを簡単に処理できます。

Promiseとasync/awaitのエラーハンドリング

非同期処理では、エラーハンドリングが非常に重要です。Promiseの場合、catch()メソッドを使用してエラーをキャッチします。async/awaitの場合、try…catch構文を使用します。

async function fetchData() {
  try {
    const response = await fetch('https://example.com/data');
    if (!response.ok) {
      throw new Error(HTTP error! status: ${response.status});
    }
    const data = await response.json();
    console.log('Data:', data);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

上記の例では、fetch APIを使用してデータを取得していますが、APIリクエストが失敗した場合、throw new Error()でエラーを発生させ、catchブロックでエラーを処理しています。

エラーハンドリングを適切に行うことで、アプリケーションの安定性を向上させることができます。

TypeScript非同期処理の応用例

Promiseとasync/awaitは、様々な非同期処理に応用できます。例えば、複数のAPIリクエストを並行して実行したり、タイマー処理を実装したりすることができます。

async function fetchMultipleData() {
  try {
    const [data1, data2] = await Promise.all([
      fetch('https://example.com/data1').then(response => response.json()),
      fetch('https://example.com/data2').then(response => response.json()),
    ]);
    console.log('Data1:', data1);
    console.log('Data2:', data2);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

上記の例では、Promise.all()を使用して、2つのAPIリクエストを並行して実行しています。これにより、処理時間を短縮することができます。

また、タイマー処理では、setTimeout()関数をPromiseでラップすることで、async/awaitで扱いやすくすることができます。

function delay(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}
async function run() {
  console.log('Start');
  await delay(1000);
  console.log('After 1 second');
}
run();

参考リンク

まとめ

この記事では、TypeScriptで非同期処理を扱うためのPromiseとasync/awaitについて解説しました。これらの機能を理解し、適切に活用することで、より効率的で読みやすいコードを書くことができます。エラーハンドリングも忘れずに行い、安定したアプリケーションを構築しましょう。