JavaScript の非同期プログラミングは、徐々に誰にでも受け入れられてきています。以前は、コールバックのネスト、setTimeout、setInterval などを使用して実装するのが一般的でした。コードは非常に直感的ではなく、コード ロジック全体を見ないとすぐに理解するのは困難です。 。 Javascript の非同期関数には、おそらく I/O 関数 (Ajax、postMessage、img ロード、スクリプト ロードなど)、タイミング関数 (setTimeout、setInterval) などが含まれます。
複雑なアプリケーションでは、多くの場合、複数の層のネストが存在し、一部のステップが完了していないため、プログラム例外が発生することはよく知られています。たとえば、DOM にノードを挿入すると、次のようになります。インジェクション後、ノードが動作するまで待つ必要があります。多数のノードがインジェクトされると、時間を把握するのが困難になることがよくあります。コードがサードパーティの API データに依存している場合。 API 応答の遅延を知る方法はなく、結果が返されるまでアプリケーションの他の部分がブロックされる可能性があります。 Promise は、ノンブロッキングでコードから完全に切り離されているため、この問題に対するより良い解決策を提供します。
それでは、JavaScript の非同期プログラミングについて見てみましょう。まず、比較的人気のある Promises/A 仕様を見てみることをお勧めします。
約束/仕様
注: 理解を容易にするため、説明は Promise/A 仕様と異なる場合があります。
CommonJS の Promises/A 仕様は、API インターフェイスを標準化することで非同期プログラミングを簡素化し、非同期ロジック コードを理解しやすくしています。
Promise/A 仕様に従う実装を Promise オブジェクトと呼びます。Promise オブジェクトには、最初に作成されたときに未履行 (未履行)、履行 (完了)、失敗 (失敗/拒否) の 3 つの状態しかありません。 ) ステータスの場合、ステータスは未履行 (未履行) から履行済み (完了)、または未履行 (未履行) から失敗 (失敗/拒否) にのみ変更できます。一度ステータスがフルフィルメント(完了)または失敗(失敗/拒否)になると、ステータスを再度変更することはできません。
Promises/A 仕様は、プログラム内の遅延 (または将来) の概念を記述するためのソリューションを提供します。主なアイデアは、メソッドを実行してから他のメソッドをコールバックする前に結果が返されるのをアプリケーションをブロックするのではなく、将来のリスニングに対応するために Promise オブジェクトを返すことです。満たされた状態と失敗した状態の両方を監視できます。 Promise は、Promise オブジェクトを返す then インターフェイスを実装することでコールバックを登録します。
Then インターフェイスは、Promise のさまざまな状態を監視するために使用されます。 fulfuledHandler は履行済み (完了) ステータスを監視するために使用され、errorHandler は失敗 (失敗/拒否) ステータスを監視するために使用され、progressHandler は未履行 (未完了) ステータスを監視するために使用されます。 Promise は、未履行 (未完了) イベント監視の実装を強制しません (たとえば、古いバージョンの jQuery (1.5、1.6) の Deferred は Promise 実装であることがわかっていますが、未履行 (未完了) イベントの監視は実装されていません)状態を確認し、progressHandler をコールバックします)。
一般に、then インターフェイスは元の Promise オブジェクトではなく、新しい Promise オブジェクトを返すと考えられています。この新しい Promise オブジェクトは、元の Promise オブジェクトのセットのみを含むと理解できます。このメソッドは元の Promise オブジェクトの状態を観察することしかできませんが、遅延オブジェクトの内部状態を変更することはできません。これにより、複数の呼び出し元間の競合を回避でき、複数の呼び出し元は他の呼び出し元に影響を与えることなく新しい Promise オブジェクトの状態を変更できます。
さらに、Promise は、状態遷移を実装するための 2 つのインターフェイスを提供します。解決 (実装ステータスが未完了から完了に変更される) と拒否 (実装ステータスが未完了から拒否または失敗に変更される) です。
理解を助けるために写真を送信してください:
Promise を使用すると、同期的な考え方で非同期ロジックを作成できます。非同期関数では、try/catch を使用して例外をキャッチしたり、例外をスローしたりすることはできません。 Promise を使用すると、errorHandler を直接明示的に定義できます。これは例外をキャッチするのと同じです。
以下は、Promises/A 仕様に準拠するいくつかのクラス ライブラリ (when、q、rsvp.js、jQuery.Deferred など) です。