目次を表示
進捗状況
0%
2024-11-04
Async/Awaitと非同期処理の利用法まとめ
Async/Awaitの利用法と非同期処理のまとめ
ハンズオン
https://github.com/soutaschool/karan-async-await-performance
結論
リクエストが同時に処理されるか、順番に処理されるか。
複数の非同期処理を効率的に実行してパフォーマンスの向上に繋げることができる。
リクエスト数が多い場合に顕著なパフォーマンス向上をもたらす。
flowchart TB
subgraph 同期処理
StartS(開始) --> Request1S(リクエスト1)
Request1S --> Wait1S(待機1)
Wait1S --> Response1S(レスポンス1)
Response1S --> UpdateProgress1S(進捗更新1)
UpdateProgress1S --> Request2S(リクエスト2)
Request2S --> Wait2S(待機2)
Wait2S --> Response2S(レスポンス2)
Response2S --> UpdateProgress2S(進捗更新2)
UpdateProgress2S --> EndS(終了)
EndS --> DisplayTimeS(処理時間表示)
end
subgraph 非同期処理
StartA(開始) --> SendAllA(全リクエスト送信)
SendAllA --> WaitAllA(全レスポンス待機)
WaitAllA --> Response1A(レスポンス1)
WaitAllA --> Response2A(レスポンス2)
Response1A --> UpdateProgress1A(進捗更新1)
Response2A --> UpdateProgress2A(進捗更新2)
UpdateProgress1A --> EndA(終了)
UpdateProgress2A --> EndA(終了)
EndA --> DisplayTimeA(処理時間表示)
end
StartS --> 同期処理
StartA --> 非同期処理
実際のパフォーマンス比較
今回は5、10、15のそれぞれのリクエスト回数でパフォーマンスを確認。
非同期を利用することによって効率的に処理を行うことができることを可視化できる。
スピード感
5件のリクエストの場合。
非同期処理
必要な背景
Javascript自体はシングルスレッドで動作。
そのため、時間のかかる処理があると、他の処理がブロックされてしまう。
それを避けるためWeb APIやNode.jsの内部機構によってバックグラウンド処理を行い非同期処理を実現する。
恩恵
- 様々な処理をバックグラウンドで実行することで、UIがフリーズするのを防ぎ滑らかに保つ
- CPUやネットワーク帯域などを効率よく利用できる
- 総時間が短縮され、パフォーマンスの向上につながる
パフォーマンス
同期処理
リクエストが順番に実行 … 全体の処理時間はそれぞれのリクエストの合計。
リクエスト1が1秒、リクエスト2が1秒、リクエスト3が1秒かかる場合、合計3秒
非同期処理
リクエストが同時に実行 … 全体の処理時間は最も時間のかかるリクエストの時間
リクエスト1が1秒、リクエスト2が2秒、リクエスト3が1秒かかる場合、合計2秒
Promise
非同期処理の結果や状態を表す。
Pending
まだ完了も失敗もされていない状態
Fulfilled
非同期処理がバックグラウンドで完了した状態
Rejected
非同期処理が失敗した状態
Async / Await
async / await / try...cacheを組み合わせることでPromiseの状態を表現できる。
sequenceDiagram
participant ユーザー
participant アプリ
participant Fetch
ユーザー->>アプリ: fetchData() を呼び出す
アプリ->>Fetch: HTTP GETリクエストを送信 (Promise Pending)
Fetch-->>アプリ: レスポンスデータでResolve または エラーでReject
アプリ-->>ユーザー: 結果またはエラーをログに出力
Async
関数が常にPromiseを返すようになる。
Await
async関数内のみで利用が可能。
Promiseが解決または拒否されるまで関数の実行を一時停止する。
Try…cache
awaitによる非同期処理のエラーの補足ができる。
// 非同期関数の定義
async function fetchData() {
try {
// Promiseがpending状態になる
const response = await fetch("http://localhost:3000/api/data");
// Promiseがfulfilled状態に解決された場合
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
// Fulfilledの場合に実行
console.log(data);
} catch (error) {
// Promiseがrejected状態になった場合に実行
console.error(error);
}
}
// 非同期関数の呼び出し
fetchData();