Promiseの状態に対する理解と基本的な使い方

5887 ワード

Promise状態の理解
new Promiseで実装されたPromiseオブジェクトは3つの状態があります.
「has-resolution」-Fulfilled
レスlove(成功時)、オンフルフィルを呼び出します.
「has-rejection」-Reject
reject(失敗時)Rejectedを呼び出します
「unresolive」-Pending
reolveでもreject状態でもなく、Promiseが作成された直後の初期化状態です.
ノート:
1、Chromeから出力されたresoveはPromise{[[PromiseStatus]]:「pending」、[[PromiseValue]:undefined]、[[PromiseStatus]]に格納されているのがPromiseの状態ですが、公開訪問していないユーザーAPIは、まだ内部の状態を確認できません.
2、Promiseの中のthenのコールバックは一回だけ呼び出されます.Promiseの状態はPendingからFulfilledまたはRejectdに変化するだけで、不可逆です.
thenとcatchは新しいPromiseに戻ります.
Promiseではthenでもcatchでも、新しいPromiseオブジェクトに戻ります.
  var aPromise = new Promise(function (resolve) {
  resolve(100);
    }); 

 var thenPromise = aPromise.then(function (value) {
  console.log(value);
 });

 var catchPromise = thenPromise.catch(function (error) {
  console.error(error);
 });
 console.log(aPromise !== thenPromise); // => true
 console.log(thenPromise !== catchPromise);// => true
以下のようにチェーンコールを別々に書くのは成功しません.
//1:同じpromiseオブジェクトに対して同時にthenメソッドを呼び出す
 var aPromise = new Promise(function (resolve) {
 resolve(100);
 });

 aPromise.then(function (value) {
 return value * 2;
 });
   aPromise.then(function (value) {
   return value * 2;
 });
 aPromise.then(function (value) {
  console.log("1: " + value); // => 100
 });
thenメソッドを呼び出すたびに新しいPromiseが返されるため、最終的な出力は100 2ではなく100になる.
Promise.allの使用
関連していない複数の非同期タスクを全部実行してから後の操作を実行する必要がある場合、Promise.allを使用して、Promiseのオブジェクトの配列をパラメータとして受信します.この配列のすべてのPromiseオブジェクトがすべてreolveまたはrejectになったとき、後の.thenを呼び出します.
ここでは、2つの互いに無関係な非同期操作が同時に実行され、各Promiseの結果(すなわち、各Promiseのresoveまたはreject時に渡されるパラメータ)とPromise.allに渡されるPromise配列の順序が一致することを説明する必要がある.つまり、TaskaとTaskyBの2つの非同期的な操作があると仮定して、プロミゼ.all(Taska,TaskyB)が導入された場合、完了後に送信される.thenの順序は「Task A,TaskyB」である.
 function setTime(time){
 return new Promise((resolve)=>{
 setTimeout(()=>resolve(time),time);
  })
 }
let startTime=Date.now()
Promise.all([setTime(1),setTime(100),setTime(200)])

   .then((value)=>{
     console.log(value);    //[1,100,200]
     console.log(Date.now() - startTime); //203
   });
上の関数の出力値から、Promise.all()の非同期操作は同時に実行され、そして.then()の順序はPromise.all()の順序と同じであることが分かります.最終実行時間は約200 msで、なぜ200 msではないのか、ここではsetTimeoutに関する正確な問題に関してはここで議論しない.
Promise.raceの使用
Promise.rance(Promise.rance)の使い方はPromise.all(Promise.all)と似ていますが、受信したすべてのPromiseがFulFilledまたはReject状態になってから後の処理が続けられます.Promise.rance()は一つのPromiseがある限り、FulFillelledまたはReject状態になり、処理が継続されます.これはPromise.all()が実行し、演算し、Promise.rance()が実行または演算するのに相当します.しかし、ここにちょっと注意が必要です.
var taskA = new Promise(function (resolve) {
    setTimeout(function () {
        console.log('this is taskA');
        resolve('this is taskA');
    }, 4);
});
var taskB = new Promise(function (resolve) {
    setTimeout(function () {
        console.log('this is taskB');
        resolve('this is taskB');
    }, 1000);
});

Promise.race([winnerPromise, loserPromise]).then(function (value) {
console.log(value);
 });

 /*
     :
this is taskA
this is taskA
this is taskB
*/
ここから分かるように、最初のPromiseがFulFiled状態になってからthenに戻ると、後のPromiseは運転を停止せずに実行を続けています.つまり、Promise.raceは、最初のpromiseオブジェクトがFulfilledになった後、他のプロmiseオブジェクトの実行をキャンセルしません.
Promise.resoveの使用
Promiseのチェーン呼び出しでは、各task間に相互依存性が存在する可能性があり、例えばTaskaがTaskyBにパラメータを転送したい場合、以下のように、
/* 1.  Promise.resolve()  */
let task1 = (value1)=>value1+1;
let task2 = (value2)=>value2+2;
let task3 = (value3)=>{console.log(value3+3)};

Promise.resolve(1).then(task1).then(task2).then(task3);//console => 7


/* 2.       Promise*/
function task1(value1){
return new Promise((resolve,reject)=>{
 if(resolve){
  resolve(value1+1);
}else{
  throw new Error("throw Error @ task1");
}
});
}

function task2(value2){
return new Promise((resolve,reject)=>{
 if(resolve){
  resolve(value2+2);
}else{
  throw new Error("throw Error @ task1");
}
});
}
function task3(value3){
return new Promise((resolve,reject)=>{
 if(resolve){
  console.log(value3+3);
}else{
  throw new Error("throw Error @ task1");
}
});
}

 task1(1).then(task2).then(task3);//console => 7
reloveとrejectについては、以下の2つの説明があります.
Reselove関数は、Promiseオブジェクトの状態を「未完成」から「成功」に変化させ、非同期操作が成功したときに呼び出し、非同期操作の結果をパラメータとして伝達する役割を果たします.
reject関数の役割は、Promiseオブジェクト状態を「未完成」から「失敗」に変化させ、非同期操作に失敗したときに呼び出し、非同期操作で報告されたエラーをパラメータとして伝達することです.
したがって、上記の例とそれらの使い方から、後のtaskに伝えたい場合は、2つの方法があります.
Promise.resove()を使用してPromiseを起動すれば、例1のように伝達が必要なパラメータの前にreturnを加えれば良い.
Promiseを利用して任務を包装したら、次のtaskに伝えたいパラメータをresoliveに渡せばいいです.
特别な说明:もしresoveが必要ならば()後で複数のパラメーターを伝えて、直接resove(a 1,a 2,a 3)を书くことができなくて、このように第1つの伝达するパラメーターを得ることしかできなくて、行列あるいは対象で伝达に行きます.
let obj = {a1:a1,a2:a2,a3:a3};
resolve(obj)
//or
let arr =[a1,a2,a3];
resolve(arr);
Promiseのrejectと非同期操作errorの理解
function ReadEveryFiles(file){
return new Promise((resolve,reject)=>{
    if(resolve){
        fs.readFile(`${__dirname}/jQuery/${file}`,(err,data)=>{
            if(err){
                console.log(err);
            }else{
                let obj = {data:data,file:file};
                resolve(obj);
            }
        });
    }else{
        //promise reject error
    }
 });
}
ここのreadFileのerrorとPromiseのrejectは違っています.一つはreadFileの過程で発生したエラーです.もう一つはPromiseが処理をする時に発生したエラーです.このように理解できます.もしファイルを読み込むことができたら、Promiseはまたこの非同期操作で得られたデータを処理してください.Promiseがこれらの操作をする時にエラーが発生するかもしれません.
転載先:https://juejin.im/post/5a58551ef265da3e51330a8e