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

3813 ワード

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は以下のように書き換えます.
 
  
function f1(){
var dfd = $.Deferred();
setTimeout(function () {
// f1
dfd.resolve();
}, 500);
return dfd.promise;
}
このように書く利点は、コールバック関数がチェーン式の書き方になり、プログラムの流れがよく見えます.そしてセットの方法があり、多くの強力な機能を実現できます.
例えば、複数のコールバック関数を指定します.
f 1().then(f 2).then(f 3)また例えば、エラーが発生した場合のコールバック関数を指定します.
f 1().then(f 2).fail(f 3);また、前の3つの方法にはない利点があります.タスクが完了したら、再度コールバック関数を追加してください.このコールバック関数はすぐに実行されます.だから、ある事件や信号を逃したかどうか心配しなくてもいいです.この方法の欠点は編纂と理解で、すべて比較的に難しいです.