1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人的アドカレAdvent Calendar 2024

Day 5

Promise.allを使用した並列処理で非同期処理の時間を短縮する

Posted at

はじめに

本記事では、Promise.all() メソッドを使用して非同期処理を並列実行を実装していきます。実際のAPIを使用する代わりに、遅延を伴う非同期関数を使用してデータフェッチをシミュレートします。

Promise.allとは?

Promise.all() は、複数の非同期処理を並列して実行し、すべての非同期処理が解決されたときに新しいPromiseを返すJavaScriptのメソッドです。

  • パフォーマンスの向上
    例えば下記のように互いに依存関係のない複数の非同期処理があった場合にasync awaitで直列に実行していくと、4500msかかります。

    • 処理1(2000ms)
    • 処理2(1000ms)
    • 処理3(1500ms)

これら3つの非同期処理に対して Promise.all() を使用することで、最も長い処理(2000ms)程度で完了します。

image.png

並列非同期処理のシミュレーション

  • fetchSimulation
    APIコールを見立ててfetchSimulation 関数を定義しています。第2引数で指定した秒数遅延させた後にデータを返します。

  • fetchDataParallel
    Promise.all()を使用して、異なる遅延を持つ3つの非同期処理(ユーザー、投稿、コメントのフェッチをシミュレート)を並列して実行します。結果をコンソールに出力し、全体の実行時間も計測します。

index.js
// データフェッチサンプル例
function fetchSimulation(dataType, delay) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve({ process: `処理: ${dataType} 完了`, time: new Date() });
      }, delay);
    });
}
  
async function fetchDataParallel() {
    try {
        console.time('Fetch time');
        const startTime = new Date();
        const completionOrder = [];

        // 3つの非同期処理を Promise.all で実行
        const results = await Promise.all([
            // 非同期処理1
            fetchSimulation('非同期処理1', 2000).then(result => {
                completionOrder.push('非同期処理1');
                return result;
            }),
            // 非同期処理2
            fetchSimulation('非同期処理2', 1000).then(result => {
                completionOrder.push('非同期処理2');
                return result;
            }),
            // 非同期処理3
            fetchSimulation('非同期処理3', 1500).then(result => {
                completionOrder.push('非同期処理3');
                return result;
            })
        ]);
        console.timeEnd('Fetch time');
        
        console.log('完了順序:', completionOrder.join(' -> '));
        
        // 実行結果の確認
        results.forEach(result => {
        // 各非同期処理の完了時間を算出
        const timeDiff = new Date(result.time) - startTime;
        console.log(`${result.process} (完了時間: ${timeDiff}ms)`);
        });
    } catch (error) {
        console.error('エラーが発生しました:', error.message);
    }
}
  
fetchDataParallel();

動作確認

次のコマンドで処理を実行します。

node index.js

実行結果のログから処理が並列して行われていることが分かります。

実行結果
Fetch time: 2.005s
完了順序: 非同期処理2 -> 非同期処理3 -> 非同期処理1
処理: 非同期処理1 完了 (完了時間: 2004ms)
処理: 非同期処理2 完了 (完了時間: 1011ms)
処理: 非同期処理3 完了 (完了時間: 1501ms)

image.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?