javascript非同期プログラミングの4つの方法


Javascript言語の実行環境は「シングルスレッド」であることを知っているかもしれません。「シングルスレッド」とは、一回に一つしかできないミッションのことです。複数のタスクがある場合は、前のタスクを完了し、後のタスクを実行しなければなりません。これを類推します。このようなモードのメリットは実現が比較的簡単で、実行環境が比較的単純であることです。悪いところは一つのタスクがある限り、時間がかかります。後のタスクは並んで待つ必要があります。プログラム全体の実行を遅らせます。よくあるブラウザは無応答(仮死)で、あるJavascriptコードが長時間運行されているため、ページカード全体がこの場所にあるため、他のタスクは実行できません。この問題を解決するために、Javascript言語はタスクの実行モードを二つに分けます。同期(Synchronous)と非同期(Aynchronous)。同期モードとは前の段階のモードで、後のタスクは前のタスクが終了するのを待ってから実行し、プログラムの実行順序はタスクの並び順と一致し、同期します。非同期モードは、すべてのタスクに1つ以上のコールバック関数があり、前のタスクが終了した後、後のタスクを実行するのではなく、コールバック関数を実行し、後のタスクは前のタスクが終了するまで実行しないので、プログラムの実行順序はタスクの並べ替え順序と一致しない、非同期です。非同期モード「非常に重要です。ブラウザ側では、時間がかかる長い操作は例外的に実行し、ブラウザが応答を失うのを避けるべきであり、一番いい例はAjax操作である。サーバー側では、「非同期モード」は、実行環境がシングルスレッドであるため、すべてのhttp要求を同期させるとサーバ性能が急激に低下し、すぐに応答が失われます。一、コールバック関数
これは非同期プログラミングの最も基本的な方法である。
2つの関数f 1とf 2があると仮定し、前者の実行結果を待つ。

f1();
f2();
f 1が時間がかかるタスクであれば、f 1を書き換え、f 2をf 1のコールバック関数として書くことが考えられます。

function f1(callback){
setTimeout(function () {
// f1
callback();
}, 1000);
}
 
実行コードは以下のようになります。
f 1(f 2)このようにして、同期動作を非同期操作に変えました。f 1はプログラムの実行を滞らせません。先にプログラムを実行する主要なロジックに相当します。時間がかかる操作を実行を遅らせます。
コールバック関数の利点は、単純で分かりやすく配置されており、欠点はコードの読み取りと維持に不利であり、各部分間の高度結合(Couplling)は、プロセスが混乱し、各タスクは一つのコールバック関数しか指定できない。
二、事件の傍受
もう一つの考えはイベント駆動モードを採用することです。タスクの実行はコードの順序に依存せず、あるイベントが発生するかどうかに依存します。
それともf 1とf 2を例にしますか?まず、f 1にイベントを結びつける(ここで使うjQueryの書き方)。

f1.on('done', f2);
上の行のコードの意味は、f 1がdoneイベントが発生したらf 2を実行するということです。そして、f 1を書き換えます。

function f1(){
setTimeout(function () {
// f1
f1.trigger('done');
}, 1000);
}
f 1.trigger('done')は、実行が完了したら、直ちにdoneイベントをトリガし、f 2の実行を開始することを示しています。
この方法の利点は、複数のイベントを結びつけることができ、各イベントは複数のコールバック関数を指定することができ、かつ「結合解除」(Decoupling)が可能であり、モジュール化を容易にすることができるということである。欠点はプログラム全体がイベント駆動型になり、動作フローが非常に不明瞭になります。
三、リリース/購読
前の節の「事件」は、完全に「信号」と理解できます。
私たちは、あるミッションを実行した「信号センター」があると仮定して、信号センターに信号を送ると、他のタスクは信号センターに「購読」(subscribe)という信号を送って、いつ自分が実行できるかを知ることができます。これは「公開/購読モード」と呼ばれ、また「観察者モード」とも呼ばれています。
このモードは様々な実装があり、以下はBen AlmanのTinPub/Subを採用しています。これはjQueryのプラグインです。
まず、f 2は「信号センター」jQueryに「done」信号を購読する。

jQuery.subscribe("done", f2);
の後、f 1は次のように書き換えられる。

function f1(){
setTimeout(function () {
// f1
jQuery.publish("done");
}, 1000);
}
 
jQuery.publish(「done」)は、f 1の実行が完了したら、「信号センター」jQueryに「done」信号を送信し、f 2の実行を誘発するという意味です。
また、f 2の実行が完了したら、購読をキャンセルすることもできます。

jQuery.unsubscribe("done", f2);
この方法の性質は「イベントモニター」と類似しているが,後者より明らかに優れている。私たちは「メッセージセンター」を見ることによって、どのぐらいの信号があるか、どのぐらいの予約者がいるかを知ることができます。それによってプログラムの運行を監視します。
四、Promisesオブジェクト
PromisesオブジェクトはCommonJS作業グループが提案した仕様で、非同期プログラミングのために統一インターフェースを提供することを目的としています。
簡単に言えば、各非同期タスクはPromiseオブジェクトに戻り、オブジェクトにはthenメソッドがあり、コールバック関数の指定が可能です。例えば、f 1のコールバック関数f 2は、次のように書き換えられます。

f1().then(f2);
このように書く利点は、コールバック関数がチェーン式の書き方になり、プログラムの流れがよく見えます。セットになっている方法で、多くの強力な機能を実現することができます。
例えば、複数のコールバック関数を指定します。
f 1().then(f 2).then(f 3)また例えば、エラーが発生した場合のコールバック関数を指定します。
f 1().then(f 2).fail(f 3);また、前の3つの方法にはない利点があります。タスクが完了したら、再度コールバック関数を追加してください。このコールバック関数はすぐに実行されます。だから、ある事件や信号を逃したかどうか心配しなくてもいいです。この方法の欠点は編纂と理解で、すべて比較的に難しいです。