0
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?

JavaScriptにおける非同期処理設計パターン:Promiseチェーン / async-await / 並列・直列・条件分岐処理の構造設計

Posted at

概要

非同期処理とは「async/awaitで書くこと」ではない。
それは**“処理の流れ・構造・失敗・依存を意図通りに制御し、読みやすさと再利用性を両立させるための構造設計”**である。

JavaScriptにおける非同期処理は、Promise、async/await、thenチェーン、並列実行、順次処理、条件付き非同期など多様なパターンが存在する。
それらを目的に応じて設計・選択しなければ、見通しの悪いコードやバグの温床となる。


1. 非同期制御の基本形:Promise vs async/await

// Promiseチェーン
doA()
  .then(doB)
  .then(doC)
  .catch(handleError);

// async/await
async function execute() {
  try {
    const a = await doA();
    const b = await doB(a);
    await doC(b);
  } catch (e) {
    handleError(e);
  }
}
  • 同じ処理でも書き方は2通り
  • ✅ async/await は 同期的に見える非同期で可読性が高い

2. 直列処理(順番が大事)

for (const item of items) {
  await process(item); // 直列処理
}
  • ✅ 順序保証が必要なときは直列が正解
  • forEach + asyncawaitを無視される →注意!

3. 並列処理(速度最優先)

await Promise.all(items.map(item => process(item)));
  • ✅ 順序不要で すべて成功する必要があるとき
  • ❌ 途中で失敗するとすべてキャンセルされる点に注意

4. 条件付き非同期処理

if (shouldFetch) {
  await fetchData();
}

const data = isCached ? getFromCache() : await fetchFresh();
  • ✅ 状態や条件に応じて非同期を選択
  • ✅ 条件によって 同期/非同期が混在するパターンはテスト観点で要注意

5. レース構造(先に返ってきたものを使う)

const fast = await Promise.race([fromAPI(), fromCache()]);
  • ✅ 最も早いレスポンスを使いたい場合に有効
  • タイムアウト / エラーハンドリングとの組み合わせ設計が重要

6. タイムアウト付き非同期処理

function withTimeout(promise, ms) {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), ms)
  );
  return Promise.race([promise, timeout]);
}
  • ✅ ネットワークなど 不確実性の高い処理の安全弁
  • AbortController と組み合わせるとキャンセルも可能

設計判断フロー

① この非同期は順序が必要か? → 直列設計

② 複数処理は独立しているか? → 並列設計 + Promise.all

③ 条件によって非同期が変化するか? → 分岐を明示的に

④ 早く返ってきたものを採用すべきか? → Promise.race構造

⑤ ネットワーク不安定 or 外部依存があるか? → タイムアウト構造を導入

よくあるミスと対策

❌ forEach に async を使って順番が崩れる

→ ✅ for...of + await に置き換える


❌ すべて並列にしてしまい、エラー原因が特定できない

→ ✅ エラーハンドリングは try-catch or Promise.allSettled を活用


❌ 条件で await するかしないかが混乱している

→ ✅ 同期・非同期どちらでも統一的に扱えるよう設計


結語

非同期処理とは「awaitをつければ済む」ものではない。
それは**“実行順、依存関係、例外、時間制約など、あらゆる変数を制御するための設計的選択の集合体”**である。

  • 順序と独立性に応じて直列 / 並列を選び
  • 条件やレスポンスタイムに応じて制御構造を設計し
  • 例外・タイムアウト・キャンセルを含めて全体をデザインする

JavaScriptにおける非同期処理設計とは、
“不確実性を構造で飲み込み、意図を保証するための非同期の設計戦略”である。

0
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
0
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?