TypeScript中級

中級 TypeScriptで学ぶ非同期処理|アンチパターン編

導入

非同期処理は、現代のアプリケーション開発において避けて通れない重要なテーマです。特に、TypeScriptを用いた非同期処理では、型安全を活かしつつ、効率的にコードを書くことが求められます。しかし、実務においては非同期処理の設計において様々なアンチパターンに直面することが多いです。本記事では、具体的なシチュエーションを通じて、ありがちな失敗例とその改善策を検討します。

教科書レベルの解説(非同期処理)

重要な概念の整理

非同期処理とは、処理が完了するのを待たずに次の処理を進める手法です。JavaScriptやTypeScriptでは、Promiseやasync/awaitを利用して、非同期処理を簡潔に扱うことができます。これにより、UIの応答性を保ちながら、バックグラウンドでデータを取得したり、計算を行ったりすることが可能です。

コード例(TypeScript)


async function fetchData(url: string): Promise {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error('Network response was not ok');
    }
    return await response.json();
}

async function processData(url: string) {
    try {
        const data = await fetchData(url);
        console.log(data);
    } catch (error) {
        console.error('Fetch error:', error);
    }
}

コードの行ごとの解説

  1. async function fetchData(url: string): Promise { – 非同期関数fetchDataを定義。引数としてURLを受け取り、Promiseを返す。
  2. const response = await fetch(url); – fetch APIを使って指定されたURLからデータを取得。awaitにより、レスポンスを待つ。
  3. if (!response.ok) { throw new Error('Network response was not ok'); } – レスポンスが正常でない場合、エラーをスロー。
  4. return await response.json(); – レスポンスをJSON形式で返却。
  5. async function processData(url: string) { – もう一つの非同期関数processDataを定義。
  6. const data = await fetchData(url); – fetchDataを呼び出し、データを取得。
  7. console.log(data); – 取得したデータをコンソールに出力。
  8. catch (error) { console.error('Fetch error:', error); } – エラーが発生した場合、エラーメッセージを出力。

アンチパターン編

非同期処理においてよく見られるアンチパターンの一つは、複数の非同期操作を直列で行うことです。例えば、あるデータを取得した後に別のデータを取得する場合、各操作をawaitで待つと、全体の処理時間が長くなります。以下にその例を示します。


async function fetchMultipleData(url1: string, url2: string) {
    const data1 = await fetchData(url1);
    const data2 = await fetchData(url2);
    console.log(data1, data2);
}

上記のコードでは、最初のfetchDataが完了するまで次のfetchDataが実行されません。この場合、両方のデータを同時に取得することで、処理時間を短縮できます。改善策としては、Promise.allを使用する方法が考えられます。


async function fetchMultipleData(url1: string, url2: string) {
    const [data1, data2] = await Promise.all([fetchData(url1), fetchData(url2)]);
    console.log(data1, data2);
}

Promise.allを使用することで、両方の非同期操作を並行して実行し、全体の処理時間を短縮できます。このように、非同期処理の設計を見直すことで、パフォーマンスを大幅に向上させることが可能です。

まとめ

  • 非同期処理における直列実行は、処理時間を不必要に延ばす。
  • Promise.allを活用することで、複数の非同期操作を同時に実行できる。
  • 非同期処理の設計を見直すことで、アプリケーションのパフォーマンス向上が期待できる。