コンテンツへスキップ
Angular Async/Await: なぜ必要なのか、どのように使用するのか

Angular Async/Await: なぜ必要なのか、どのように使用するのか

AngularのAsync Awaitとは何ですか、またコールバック地獄を防ぐためにそれをどのように使用するのですか?最新の記事で答えを学びましょう

6min read

Angularは優れたフレームワークですが、非同期コードを記述し、非同期呼び出しを行うのは困難です。特に、Async/Await とAngular Promiseのどちらを選ぶか決められない場合。したがって、このチュートリアルでは、例とコード スニペットを通じて、Async/Await と Promise の違いを理解するのに役立ちます。また、コールバック地獄を簡単に回避する方法を説明し、Ignite UI for Angularコンポーネントの助けを借りてJavaScriptでAsync / Awaitを使用する方法を示します。

Try Ignite UI for Angular

Angularの非同期コードとは何ですか?

非同期コードとは、単にコードが順番に実行されず、プロセスがマルチスレッドを含むことを意味します。これは、プライマリ アプリケーション スレッドを中断することなく、別のコード ブロックを実行する並列プログラミングの形式です。非同期コードの実行は、大規模なイテレーションの場合や複雑な操作がある場合に便利です。

ただし、Angularアプリの操作を簡略化し、実行時間の短い場合は、非同期プログラミングは避けた方がよいでしょう。通常、非同期コードは読みにくいため、読みやすさを向上させ、開発者にとってよりシンプルにできるものはすべて、品質の向上と見なされます。そして、JavaScriptにはこれに対処するための独自のトリックとメカニズムがあります。

How JavaScript Handles Asynchronous Code

デフォルトでは、JavaScript は同期シングルスレッド言語であり、一度に 1 つのステートメントを上から下に実行します。つまり、新しいスレッドとプロセスは、メイン プログラム フローと並行してコードを実行できません。1 つの呼び出しスタックと 1 つのヒープ メモリがあり、コードを順番に実行し、次のコードに進む前にコードの実行を完了する必要があります。すべてが順番に行われます。しかし、たとえば、1 つのページで複数の AJAX 呼び出しを行う必要がある場合はどうなるでしょうか。

最初に思い浮かぶ解決策は、コールバックの使用です。しかし、それらはプログラマーに「コールバック地獄」として知られる大きな問題につながります。基本的に、これはネストされた promise-then コード構造であり、複数のリクエストとデータ変換を行う必要があるため、多くの場合、コードの保守や読み取りが難しくなり、アプリのスケーラビリティが低下します。

コールバックは、Angularアプリの非同期コードを処理するのに最適な方法ではないことがわかりました。では、どうすればよいでしょうか。もしかしたら、Angular約束なのでしょうか?このパターンは、非同期操作を効率的にラップし、完了時に通知します。しかし、よりクリーンで保守性の高いコードを提供するとはいえ、Angular Promise を使用することは、同じコードを何度も再利用することが多く、DRY (Don't Repeat Yourself) principle.cl と矛盾するため、最適なソリューションではありません

ありがたいことに、Angularには Async/Await があります。

Using Async/Await in Angular

JavaScript の最も優れた改善点の 1 つは、ECMAScript 7 で導入された非同期/待機機能です。基本的に、Async/Await は Promise の上で動作し、非同期コードを同期的に記述できます。これにより、コードが簡素化され、フローとロジックがより理解しやすくなります。

then と catch チェーンは使用されなくなったため、try/catch を実行してエラーを処理できることに注意してください。

Async/Await vs Promise: 違いは何ですか?

Async/Await と Promise の違いを示すために、より消化しやすく簡潔な方法で比較する表を作成しましょう。

Promise 

Async/Await 

Promise は、将来のある時点で実行を完了することが保証されている操作です

Async/Await は Promise の上に構築されています。これらは promise の構文上の砂糖であり、コードをより同期的に見せます

エラー処理は、.then() メソッドと catch() メソッドを使用して行われます

エラー処理は、try() メソッドと catch() メソッドを使用して行われます

Promise の連鎖を理解するのが難しい場合があります

Async と await を使用すると、コードが読みやすく、プログラムの流れを理解しやすくなります

保留中、解決済み、拒否の3つの状態があります

解決済みまたは拒否された Promise を返します

Angular Data Gridで両方の構文を持つ 1 つの例を作成し、違いを見てみましょう。API に対して 2 つの非同期呼び出しを行う関数があり、1 つはユーザー データを取得するため、もう 1 つはユーザーがメンバーであるクラブを取得するためのものです。2 番目の呼び出しは最初の呼び出しに依存するため、他のリクエストに進む前に getUserData() を完了する必要があります。どちらの構文も読みやすいですが、もちろん .then() や .catch() で promise を使用すると、コールバック地獄に陥り、コードの理解と保守が難しくなります。

const makeRequest = () =>
     getUserData()
    . then(user => getClubsForUser(user.id))
    .then(console.log)
    .catch(err => console.log('Error: ' + err.message));
const makeRequest = async () => {
    try {
        let user = await getUserData();
        let clubs = await getClubsForUser(user.id);
        console.log(clubs);
     }
    catch(err) {
        console.log(err.message);
   }
};

 

Ignite UI Angularで Async/Await を使用する方法

フォーム入力からユーザーデータを取得し、APIにリクエストを送信してユーザーの資格情報が正しいかどうかを確認し、正しい場合はホームページにリダイレクトする関数を作成しましょう。Ignite UI for AngularでAsync / Awaitを使用すると、このような状況で役立ちます。非同期操作であるAPIへのリクエストがあるため、awaitを使用してから、データを保存するために他に問題がない場合はawaitを使用します。

const submitLoginData = async () => { 
    try { 
         if (this.userInput.email && this.userInput.password) { 
         const response = await this.loginUser(this.userInput); 

         if (response.statusCode === 200) { 
             alert('User is successfully logged in!'); 
             await saveUserData(response.data); 
             this.router.navigate(['/']); 
         } 
         else { 
             alert(response.message); 
             this.router.navigate(['/login']); 
         }
     } 
   } 
     .catch(err) { 
         alert('Something went wrong, try again later!') 
         this.router.navigate(['/login']); 
     } 
} 

ここでは間違いなく .then() と .catch() を使用できますが、Ignite UI for Angularの Async/Await を使用すると、コードがよりエレガントに見えます。使用する構文を選択するのは、コードを書いている人次第です。ただし、スタイルを混在させるとコードが複雑になる可能性があるため、1つのアプローチに固執することをお勧めします。

Async/Await Angular Best Practices

非同期コードを処理するために async と await を使用している場合は、常にコードを try/catch ブロックに入れる必要があります。このようにして、Promise がエラーをスローしている場合でも、適切にキャッチおよび処理されるようになります。

async function loadComponents() {
     try {
         this.components = await fetchComponentsByType('charts');
     }
     .catch(err) {
         logger.error(err);
     }
}

Ignite UIを使用すると、非同期関数で promise を明示的に返す必要はありません。実際、非同期関数は常に Promise を返します。つまり、非同期関数内に Promise を作成すると、Angularアプリのパフォーマンスのオーバーヘッドが増えるだけです。

async function loadChartSelectors() {
     return Promise.resolve(['igx-data-chart', 'igx-pie-chart', 'igx-category-chart']);
}

概要

Async/Await キーワードを使用すると、コードの読み取りとデバッグが容易になります。しかし、それらを正しく使用したい場合は、約束が一般的にどのように機能するかを理解する必要があります。

Ignite UI Angular

デモを予約