ホームページ > ウェブフロントエンド > jsチュートリアル > Async/Await vs Promises: JavaScript 初心者のための簡単なガイド

Async/Await vs Promises: JavaScript 初心者のための簡単なガイド

Patricia Arquette
リリース: 2024-12-22 02:12:17
オリジナル
920 人が閲覧しました

Async/Await vs Promises: A Simple Guide for JavaScript Beginners

JavaScript がカフェラテを取りに来るまでコーヒーショップで列に並んでいるように感じたことはありますか?非同期プログラミングでは、そのように感じることがよくあります。複数の注文が同時に処理されると、待たされてしまう可能性があります。幸いなことに、Promisesasync/await などのツールにより、プロセスがスムーズかつ効率的に維持され、コードが遅延なく動き続けることが保証されます。

このガイドでは、Promise がどのように機能するか、async/await が導入された理由、およびそれによって非同期コードの作成がどのように簡素化されるかについて詳しく説明します。これらの概念を理解しようとしている初心者でも、各アプローチをいつ使用するかを明確にしたい場合でも、この記事は基本をマスターするのに役立ちます。

約束とは何ですか?

Promise は、非同期操作を処理するための JavaScript の基本的な概念です。基本的に、Promise は、後で、または決して利用できない値を表します。これは荷物の追跡番号のようなものだと考えてください。荷物がまだ手元にない場合でも、追跡番号によって荷物が配達中であるという確信が得られます (または、何か問題が発生した場合はそれを知ることができます)。

「今、後で、それとも決して」という物語に基づいて、Promise は実際には 3 つの状態のいずれかで動作します。

  • 保留中: 非同期操作はまだ完了していません。
  • 履行: 操作は正常に完了し、Promise に結果が保持されています。
  • 拒否されました: 問題が発生し、Promise にエラーが発生しました。

Promise の作成と操作には、単純な API が必要です。 Promise を定義する方法は次のとおりです:

const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => {
    const data = { id: 1, name: "JavaScript Basics" };
    resolve(data); // Simulates a successful operation
    // reject("Error: Unable to fetch data"); // Simulates a failure
  }, 1000);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

結果を処理するには、.then()、.catch()、および .finally() メソッドを Promise オブジェクトにチェーンできます。

fetchData
  .then((data) => {
    console.log("Data received:", data);
  })
  .catch((error) => {
    console.error(error);
  })
  .finally(() => {
    console.log("Operation complete.");
  });
ログイン後にコピー
ログイン後にコピー

then() メソッドのコールバックは、Promise が成功した結果で解決されると実行されます。 .catch() メソッドのコールバックは、Promise が失敗した結果で解決されたときに実行され、finally() メソッドのコールバックは、解決の結果に関係なく、Promise が解決された後に実行されます。

約束の利点

Promise は、「コールバック地獄」と呼ばれることが多い、深くネストされたコールバックに代わるクリーンな代替手段を提供します。コールバックを積み重ねる代わりに、Promise を使用すると連鎖が可能になり、操作の流れを理解しやすくなります。

doTask1()
  .then((result1) => doTask2(result1))
  .then((result2) => doTask3(result2))
  .catch((error) => console.error("An error occurred:", error));
ログイン後にコピー

これと同じコードが従来のコールバックを使用して記述されていた場合、次のようになります。

doTask1((error1, result1) => {
  if (error1) {
    console.error("An error occurred:", error1);
    return;
  }
  doTask2(result1, (error2, result2) => {
    if (error2) {
      console.error("An error occurred:", error2);
      return;
    }
    doTask3(result2, (error3, result3) => {
      if (error3) {
        console.error("An error occurred:", error3);
        return;
      }
      console.log("Final result:", result3);
    });
  });
});
ログイン後にコピー

紛らわしいですね。これが、Promise が導入されたときに JavaScript コーディング標準の変革者となった理由です。

約束の欠点

Promise は従来のコールバック関数を大幅に改善しましたが、独自の課題がないわけではありません。利点にもかかわらず、複雑なシナリオでは扱いにくくなり、コードが冗長になり、デバッグが困難になる可能性があります。

.then() チェーンを使用しても、複数の非同期操作を処理する場合、Promise によってコードが乱雑になる可能性があります。たとえば、.then() ブロックを使用した逐次操作の管理や .catch() を使用したエラー処理は、反復的で理解しにくいと感じることがあります。

const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => {
    const data = { id: 1, name: "JavaScript Basics" };
    resolve(data); // Simulates a successful operation
    // reject("Error: Unable to fetch data"); // Simulates a failure
  }, 1000);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ネストされたコールバックよりもすっきりしていますが、特に詳細なカスタム エラー処理ロジックが必要な場合、チェーン構文は依然として冗長です。さらに、チェーンの最後に .catch() を追加するのを忘れると、サイレントエラーが発生し、デバッグが困難になる可能性があります。

さらに、Promise のスタック トレースは、同期コードのスタック トレースほど直感的ではありません。エラーが発生した場合、スタック トレースには、問題が非同期フローのどこで発生したかが明確に示されない場合があります。

最後に、Promise はコールバック地獄の軽減に役立ちますが、タスクが相互依存している場合には依然として複雑さが生じる可能性があります。ネストされた .then() ブロックは、特定のユースケースで再び使用される可能性があり、解決するはずだった可読性の課題の一部を元に戻します。

非同期/待機を入力してください

ES2017 (ES8) での async/await の導入により、JavaScript での非同期プログラミングは大きな飛躍を遂げました。 Promises の上に構築された async/await を使用すると、開発者は同期コードのように見え、動作する非同期コードを作成できます。これにより、可読性が向上し、エラー処理が簡素化され、冗長性が軽減されるため、真の変革をもたらします。

非同期/待機とは何ですか?

Async/await は、非同期コードを理解し、保守しやすくするために設計された構文です。

async キーワードは、常に Promise を返す関数を宣言するために使用されます。この関数内で、 await キーワードは Promise が解決されるか拒否されるまで実行を一時停止します。これにより、複雑な非同期操作であっても、直線的で直感的なフローが実現します。

これは、上で見たのと同じコード例を async/await で簡素化する方法の例です。

fetchData
  .then((data) => {
    console.log("Data received:", data);
  })
  .catch((error) => {
    console.error(error);
  })
  .finally(() => {
    console.log("Operation complete.");
  });
ログイン後にコピー
ログイン後にコピー

Async/await を使用すると、.then() チェーンが不要になり、コードが順番に流れるようになります。これにより、特に次々に実行する必要があるタスクの場合、ロジックに従うことが容易になります。

Promise では、.catch() を使用してチェーンのすべてのレベルでエラーを捕捉する必要があります。一方、Async/await は、try/catch を使用したエラー処理を統合し、繰り返しを減らし、明確さを向上させます。

Async/await は、Promise よりも直感的なスタック トレースを生成します。エラーが発生した場合、トレースには実際の関数呼び出し階層が反映されるため、デバッグのストレスが軽減されます。全体として、async/await は同期コードの記述方法と一致しているため、より「自然」に感じられます。

Promise と async/await の比較

すでに見たように、Async/await は読みやすさの点で、特に逐次操作の場合に優れています。 Promise は、.then() および .catch() チェーンを使用すると、すぐに冗長または複雑になる可能性があります。対照的に、async/await コードは同期構造を模倣しているため、理解しやすいです。

柔軟性

特に同時タスクの場合、Promise は依然としてその役割を果たしています。 Promise.all() や Promise.race() などのメソッドは、複数の非同期操作を並行して実行する場合により効率的です。 Async/await もこのようなケースを処理できますが、同じ結果を達成するには追加のロジックが必要です。

const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => {
    const data = { id: 1, name: "JavaScript Basics" };
    resolve(data); // Simulates a successful operation
    // reject("Error: Unable to fetch data"); // Simulates a failure
  }, 1000);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

エラー処理

単一の .catch() による集中エラー処理は Promise の線形チェーンではうまく機能しますが、可読性を最大限に高めるために、チェーン全体で異なるエラー タイプに対して分散 .catch 呼び出しを使用することをお勧めします。

一方、try/catch ブロックは、特に連続タスクを処理する場合に、エラーを処理するためのより自然な構造を提供します。

パフォーマンス

パフォーマンスの点では、async/await は Promise の上に構築されているため、基本的に Promise と同等です。ただし、同時実行性が必要なタスクの場合は、Promise.all() を使用すると複数の Promise を並行して実行でき、いずれかの Promise が拒否されるとすぐに失敗するため、より効率的になります。

いつどれを使用するか

複数の API から同時にデータを取得するなど、タスクに多くの同時操作が含まれる場合は、おそらく Promise がより良い選択です。非同期コードに多くのチェーンが含まれていない場合、Promise はその単純さからその状況にも適しています。

一方、async/await は、多くのタスクを順番に実行する必要がある場合や、可読性と保守性が優先される場合に優れています。たとえば、データの取得、変換、保存などの一連の依存操作がある場合、async/await はクリーンな同期構造を提供します。これにより、操作の流れを理解しやすくなり、try/catch ブロックによる集中エラー処理が簡素化されます。 Async/await は、初心者や読みやすいコードを優先するチームに特に役立ちます。

結論

JavaScript は、非同期操作を管理するための 2 つの強力なツール、Promises と async/await を提供します。 Promise は開発者が非同期タスクを処理する方法に革命をもたらし、コールバック地獄などの問題を解決し、チェーンを可能にしました。 Async/await は Promises に基づいて構築されており、特に連続タスクの場合に、より自然で直観的に感じられるクリーンな構文を提供します。

両方のアプローチを検討したので、ニーズに最適な方を選択できるようになりました。 Promise ベースの関数を async/await に変換して、読みやすさの違いを観察してください。

詳細については、MDN Promise のドキュメントを確認するか、インタラクティブなコーディング サンドボックスを試してください。

以上がAsync/Await vs Promises: JavaScript 初心者のための簡単なガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート