ご存知かもしれませんが、JavaScript言語の実行環境は「シングルスレッド」です。
いわゆる「シングルスレッド」は、1つのタスクを一度にしか完了できないことを意味します。複数のタスクがある場合は、キューを塗り、以前のタスクを完了し、次のタスクを実行するなどする必要があります。
このモデルの利点は、実装が比較的簡単であり、実行環境が比較的簡単であることです。プログラム全体の実行。一般的なブラウザは、特定のJavaScriptコードが長い間実行されているため(デッドループなど)、この場所にページ全体を貼り付け、他のタスクを実行できないため、多くの場合、反応しません(偽の死)。
この問題を解決するために、JavaScript言語は、タスクの実行モードを同期(同期)と非同期(非同期)の2つのタイプに分割します。
「同期モード」は前のセクションのモードであり、後者のタスクが終了するのを待ってから、プログラムの実行順序は一貫しています完全に異なり、各タスクは1つ以上のコールバック関数があります(コールバック)。終了するため、プログラムの実行順序はタスクです。
「非同期モード」は非常に重要です。ブラウザ側では、ブラウザが応答を失うことを避けるために、長期操作を非同期に実行する必要があります。サーバー側では、「非同期モード」は唯一のモードです。実行環境はシングルスレッドであるため、すべてのHTTP要求を同期的に実行できる場合、サーバーのパフォーマンスは急激に低下し、すぐに応答が失われます。
1。コールバック関数
これは、非同期プログラミングの最も基本的な方法です。
2つの関数F1とF2があり、後者は前者の実行結果を待っているとします。
コードコピーは次のとおりです。
f1();
f2();
F1が時間のかかるタスクである場合、F1の書き換えとF1のコールバック関数としてF2を書き込むことを検討できます。
コードコピーは次のとおりです。
関数F1(コールバック){
setimeout(function(){
// F1のタスクコード
折り返し電話();
}、1000);
}
実行コードは次のようになります:
F1(F2);この方法では、同期操作を非同期操作に変えません。
コールバック関数の利点は、それらが簡単で理解し、展開しやすいことであり、不利な点は、さまざまなパーツの間で高度に結合された(カップリング)コードの読み取りとメンテナンスを助長していないことです。非常に混oticとして、各タスクは1つのコールバック関数のみを指定できます。
2。イベント監視
別のアイデアは、イベント主導のモデルを採用することです。タスクの実行は、コードの順序ではなく、イベントが発生するかどうかに依存します。
F1とF2を例として取りましょう。まず、F1のイベントをバインドします(ここで使用されるjQuery執筆方法)。
コードコピーは次のとおりです。
f1.on( 'done'、f2);
上記のコード行は、F1で完了したイベントが発生すると、F2が実行されることを意味します。次に、F1を書き直します。
コードコピーは次のとおりです。
関数f1(){
setimeout(function(){
// F1のタスクコード
f1.trigger( 'done');
}、1000);
}
f1.trigger( 'done')とは、実行が完了した後、完了したイベントがすぐにトリガーされ、それによってF2の実行を開始することを意味します。
この方法の利点は、複数のイベントにバインドできることであり、各イベントが複数のコールバック関数を指定できることです。欠点は、プログラム全体がイベント駆動型になり、運用プロセスが非常に不明確になることです。
3。公開/購読します
前のセクションの「イベント」は、「信号」として完全に理解できます。
「信号センター」があると仮定します。これは、「オブザーバーパターン」とも呼ばれる「Publish-Subscribeパターン」と呼ばれます。
このモデルには多くの実装があります。以下は、JQueryのプラグインであるBen Alman's Tiny Pub/Subです。
まず、F2は「doned」信号を「信号センター」jqueryにサブスクライブします。
コードコピーは次のとおりです。
jquery.subscribe( "done"、f2);
次に、F1は次のように書き換えられます。
コードコピーは次のとおりです。
関数f1(){
setimeout(function(){
// F1のタスクコード
jquery.publish( "done");
}、1000);
}
jQuery.publish( "done")とは、F1の実行が完了した後、「done」信号が「信号センター」jqueryに発行され、それによってF2の実行をトリガーすることを意味します。
さらに、F2が実行された後、登録解除も登録解除できます。
コードコピーは次のとおりです。
jquery.unsubscribe( "done"、f2);
このアプローチの性質は「イベントリスニング」に似ていますが、後者よりもはるかに優れています。 「メッセージセンター」を調べて、各信号に存在する信号の数とサブスクライバーの数を理解することで、プログラムの操作を監視できるためです。
4。オブジェクトを約束します
Promises Objectは、非同期プログラミングに統一されたインターフェイスを提供する目的で、CommonJSワーキンググループによって提案された仕様です。
簡単に言えば、そのアイデアは、各非同期タスクがPromiseオブジェクトを返すということです。これには、コールバック関数を指定できるThenメソッドがあります。たとえば、F1のコールバック関数F2は次のように記述できます。
コードコピーは次のとおりです。
f1()。then(f2);
F1は次のように書き直す必要があります(JQueryの実装はここで使用されます):
コードコピーは次のとおりです。
関数f1(){
var dfd = $ .deferred();
setimeout(function(){
// F1のタスクコード
dfd.resolve();
}、500);
DFD.PROMISEを返します。
}
このように記述する利点は、コールバック関数がチェーンライティング方法になり、プログラムの流れが非常に明確に見ることができ、多くの強力な機能を実現できる完全なサポート方法があることです。
たとえば、複数のコールバック関数を指定します。
f1()。then(f2).then(f3);
たとえば、エラーが発生したときにコールバック関数を指定します。
f1()。then(f2).fail(f3);
さらに、以前の3つのメソッドのいずれも持っていないという利点があります。タスクが完了した場合、コールバック関数を追加すると、コールバック関数がすぐに実行されます。したがって、イベントや信号を逃すことを心配する必要はありません。この方法の欠点は、書き込みと理解が比較的難しいことです。