javascript非同期操作Promise

3808 ワード

言語の特色
javascriptは一つのスレッド言語であり、同時に一つのタスクしか実行できないという意味で、他のタスクは並んで待つ必要があります.なぜ単スレッド化したのかというと、一つのスレッドがホームページでDOMを修正し、もう一つのスレッドがDOMを削除しているからです.これは絶対だめです.JavaScriptは誕生からシングルスレッドです.その理由はブラウザを複雑にしたくないからです.マルチスレッドは資源を共有し、お互いの運行結果を修正する必要があります.ウェブスクリプト言語にとっては複雑すぎます.このようなメリットは実現が便利で、悪いところは一つのタスクが消耗する時間が多いと、後のタスクが並び、プログラム全体の実行を遅らせるということです.このような遅い原因はCPUが忙しくて手が回らないのではなくて、単に1つの任務が実行するのがとても長い時間を必要とするためで、例えばAjax要求など.JavaScript言語の設計者は、IO操作を全く気にせず、待機中のタスクを保留し、先に後ろのジョブを実行することができると認識しています.IO操作が戻ってきたら、後ろを振り向いて、掛けたタスクを続けます.このメカニズムはJavaScript内部で採用されている「イベントサイクル」メカニズムです.
同期タスク
すべてのタスクは同期タスクと非同期タスクに分けられます.同期タスクとは、エンジンにかけられず、メインスレッドに並べてタスクを実行することです.前のタスクだけが実行されて、後のタスクが実行されます.
非同期タスクとは、エンジンにかけられ、メインスレッドに入らずにジョブキューに入るタスクです.エンジンだけが、あるタスクが実行できると考えています.例えば、Ajaxはサーバーからデータを返します.非同期タスクの後ろにあるコードは、非同期タスクの結果を待つことなく、すぐに実行されます.従って非同期タスクはブロッキング効果がない.
タスクのキューとイベントのループ
Javascript実行は、現在実行中のメインスレッドの他に、エンジンがタスクキューを提供しています.中には、現在のプログラム処理を必要とする様々な非同期タスクが含まれています.まず、メインラインはすべての同期タスクを実行します.同期タスクは実行された後、タスクキューを見に行きます.条件を満たすと、非同期タスクはメインスレッドに入り、実行を開始します.この時は同期タスクになります.実行が終わると、次の非同期タスクはメインスレッドに入ります.
非同期操作ソリューション
promiseオブジェクトはJavascriptの非同期操作ソリューションで、非同期操作に統一インターフェースを提供します.Promiseは、同期操作を書いているように非同期操作をすることができます.まず、Promiseはオブジェクトであり、構造関数でもあります.
function f1(resolve,reject){
  //     
  
}

let p1=new Promise(f1);

Promiseコンストラクタf 1はパラメータとして受信され、f 1は非同期動作のコードであり、その後に戻ってくるp 1はPromiseの一例である.Promsieの設計思想は、すべての非同期タスクがPromiseのインスタンスに戻ります.Priomseの例は、次のステップのコールバック関数を指定するためのthen方法がある.
var p1=new Promise(f1);
p1.then(f2);
上のコードの中で、f 1の非同期動作が完了すると、f 2が実行されます.
//     
step1(function (value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        // ...
      });
    });
  });
});

// Promise    
(new Promise(step1))
  .then(step2)
  .then(step3)
  .then(step4);
promiseの書き方がプログラムの流れを非常に明確にしていることが分かります.
Promiseオブジェクトの状態
Promiseオブジェクトは3中状態です.1.未完成2.非同期操作成功3.非同期操作失敗
状態変化は二つしかありません.未完成です.失敗しました.成功しました.
その結果、Promiseは最終的に2つしかないです.
  • 非同期動作に成功し、Promiseの例は値を返します.
  • 非同期動作に失敗し、Promsieの例はerror.
  • に戻る.
    Promise構造関数
    Javascriptはオリジナルのコンストラクタを提供してPromiseのインスタンスを生成します.
    var promise = new Promise(function(resolve, reject) {
    				if ( /*        */ ) {
    					resolve(value);
    				} else { /*        */
    					reject(new Error());
    				}
    			});
    
    上記のコードのPromise構造関数は、それぞれrejectである関数を受信します.彼らは二つの関数で、Javascriptによって提供されます.自分で実現する必要はありません.resoliveはPromiseのインスタンスの状態を成功に至らず、非同期動作の結果をパラメータとして伝達する役割をしています.reject関数の役割は、Promiseのインスタンスの状態を失敗に変えずにエラーを伝えることです.
    Promise.prototype.then
    Promiseの例のthen方法は、コールバック関数を追加するために使用される.then方法は2つのパラメータを受信できます.最初は非同期動作が成功した時のコールバック関数で、2番目は非同期動作が失敗した時のコールバック関数です.
              var p1=new Promise(function(resolve,reject){
    				 resolve("success")
    			});
    			p1.then(console.log,console.error);    //success
    			
    			var p2=new Promise(function(resolve,reject){
    				reject("error");
    			});
    			p2.then(console.log,console.error);   //error
    
    上のコードからp 1,p 2はPromiseの2つの例であることが分かります.彼らのthen方法は2つのコールバック関数を実行します.最初はインスタンスが成功した時に実行します.第2はインスタンスが失敗した時に実行します.第二の方法は省略できます.Promseのthen法は連鎖性を持っている.下のコードには4つのthenがあり、前のリターンだけが成功し、次の方法が実行されるという意味です.
    p1
      .then(step1)
      .then(step2)
      .then(step3)
      .then(
        console.log,
        console.error
      );
    
    インスタンス画像の読み込み
    var preloadImage=function(path){
    				return new Promise(function(resolve,reject){
    					let image=new Image();
    					image.onload=resolve;
    					image.onerror=reject;
    					image.src=path;
    				});
    			}
    			
    			preloadImage('https://example.com/my.jpg').then(
    			  function(e){
    				  document.body.append(e.target);
    			  }
    			).then(function(){
    				console.log("    。");
    			});