Es 6標準Promise学習ノート


Es 6は私たちにますます近づいていますnode 4.0もオリジナルブラウザを発売しpromiseも徐々にサポートしています.彼は私たちをcallback hellから離れるのを助けることができます.
なぜpromiseを使うのですか?
fs.readFile("a.json",function(e1,d1){
    if(e1){
        //todo
    }else{
        fs.readFile("b.json",function(e2,d2){
                if(e2){
                    //todo
                }else{
                    console.log(d1+d2)
                }

        })
    }

})

oh noの1階1階の千階のショートケーキの中には醜いif elseが混じっていてpromiseバージョンを見てみましょう
var promise = new Promise(function(onFulfill,onReject){
    fs.readFile("a.json",functiom(err,data){
        if(err){
            onReject(err);
        }else{
            onFulfill(data); 
        }
    });
});

promise.
    then(function(data){ 
        return JSON.parse(data)
    },function(err){
        throw new Eerror(err)
    }).
    then(function(json){
        console.log(json)
    }).catch(function(e){
        console.log(e)
    })

どんなに優雅な方法でも、ブラウザ環境で使用できます*Chrome 32、Opera 19、Firefox 29以上のバージョンでは、Promiseがデフォルトでサポートされています.*promiseがサポートされていないブラウザ環境ではpromise polyfillを使用できます.
promiseの方法
Promise.prototype.then
thenはpromiseのコアメソッドでonFulfillを受け入れ、onRejectをパラメータとしてpromiseを返します.
     var p1 = new Promise(function(fulfill,reject){
         setTimeout(fulfill,3000);
     });
     p1.then(function(){
        return "yeah"
     }).then(function(v){
        alert(v)  //yeah
     })

Promise.prototype.catch
catchパラメータとしてfunctionを受け入れるthrowはpromiseチェーンを中断してcatchに入りpromiseを返します
      var p1 =   new Promise(function(f,r){
          JSON.parse("..");
      });

      p1.then(function(){  alert(2) },function(v){  throw  "a"  })
          .then(alert)
          .catch(function(b){
              alert(b) //a
      });



       var p1 = new Promise(function(f,r){
                f(1)
       })
       p1.then(function(){
            throw  "a"
        },function(e){
            console.log("r"+e)
        })
        .catch(function(e){
            console.log(e)  //a
        })


*第2の例ではthrowがcatchに直接アクセスすることを期待しないでconsole.log("r"+e)にアクセスすることを期待しないでください.なぜなら、onRecjectはこの層thenのものではなくp 1のものであるからです.
Promise.resolve
これは静的方法です
パラメータはvalueまたはthenableオブジェクトであり、promiseを返します.
        Promise.resolve(1)
             .then(function(v){
                 console.log("solve "+v)  //solve 1
             },function(v){
                console.log("reject "+v)
             })
             .catch(function(e){
                 console.log(e)
             })
/////////////////////////////////////  thenable  ///////////////////////////////////////////////////
        Promise.resolve({
            then:function(f,r){
                f(22);
            }
        })
            .then(function(v){
                console.log("solve "+v)  //solve 1
            },function(v){
                console.log("reject "+v)
            })
            .catch(function(e){
                console.log(e)
            })



        Promise.resolve({
            then:function(f,r){
                r("ww");
            }
        })
                .then(function(v){
                    console.log("solve "+v)
                },function(v){
                    console.log("reject "+v)//reject ww
                })
                .catch(function(e){
                    console.log(e)
                })




        Promise.resolve({
            then:function(f,r){
                throw  new Error("abc")
            }
        })
        .then(function(v){
            console.log("solve "+v)
        })
        .catch(function(e){
            console.log(e)  // Error: abc(…)
        })

Promise.reject
これは静的方法です
パラメータとしてreasonを受け入れて拒否されたpromiseを返します
     Promise.reject("reason")
             .then(function(v){
                  console.log(v)
             },function(v){
                  console.log("reject "+v) //reject reason
             })
             .catch(function(e){
                 console.log(e)
             })



    Promise.reject(new Error("fail"))
            .then(alert) //   
            .catch(function(e){
                console.log(e) //Error: fail(…)
            })

Promise.all
これは静的方法です
allメソッドは反復可能なタイプを受け入れ、すべてが完了した場合にonfillfulledが呼び出され、エラーが発生した場合にエラーパラメータを持ってonRejectに入り、残りの完了または拒否はonFillfulまたはonRejectをトリガーしません.
     var p1 = new Promise(function(f,r){
            setTimeout(function(){
                f(1)
            },1000)
     })

     var p2 = new Promise(function(f,r){
         setTimeout(function(){
             f(2)
         },2000)
     })

     Promise.all([p1,p2])
            .then(function(v){  
                console.log(v); //     [1, 2]
            })  

失敗した
     var p1 = new Promise(function(f,r){
            setTimeout(function(){
                f(1)
            },1000)
     })

     var p2 = new Promise(function(f,r){
         setTimeout(function(){
             r(2)
         },2000)
     })

     Promise.all([p1,p2])
            .then(null,function(arr){  
                console.log(arr); //    2
            }) 

Promise.race
raceは反復可能なオブジェクトをパラメータとして入力し、そのうちのいずれかのpromiseオブジェクトがfillfulまたはreject状態になると、onFillfulまたはonRejectを実行し、残りの完了または拒否はonFillfulまたはonRejectをトリガーしません.
これは静的方法です
       var p1 = new Promise(function(f,r){
           setTimeout(function(v){
                r(1)
           },1000)
       })
       var p2 = new Promise(function(f,r){
           setTimeout(function(v){
                f(2);
           },5000)
       })

       var p3 = new Promise(function(f,r){
           setTimeout(function(v){
               r(3)
           },1000)
       })

       Promise.race([p1,p2,p3])
              .then(function(v){
                    console.log(v)
               },function(e){
                    console.log("  "+e) //      1
               })

実は私の理解は誰が速いかを見ることです==
*細部allとraceのパラメータp 1とp 3はいずれも1秒で配列順序に関係なくpromise宣言順序に関係なくp 1がp 3より先に宣言されるので先にトリガーされる
*raceとallは兄弟allのペアがすべて実行されてからonFullifllをトリガーしますが、raceは逆に最も速いものを獲得します.
完全な例
        new Promise(function(r,j){
         setTimeout(function(){
             r('{"name":"abc"}')
         },300)
    }).then(function(data){
        return JSON.parse(data)
    }).then(function(json){

        var  p = new Promise(function(r,j){
            setTimeout(function(){
                r(['{"name":"edf"}',json])
            },300);
            setTimeout(function(){
                j(new Error("time out"));
            },300);

        })
        return p
    }).then(function(arr){
        return  [ JSON.parse(arr[0] ),arr[1] ]
    },function(err){
        throw  err
    }).then(function(arr){
        return arr[1].name + arr[0].name
    }).then(function(str){
        console.log(str);
    })
    .catch(function(e){
         if(e.message  === "time out"){
             console.log("time out")
         }else{
             console.log(e)
         }

    })

メモに感謝します.
  • MDN
  • JavaScript Promiseミニブック(中国語版)