promiseの原理を簡単に分析する


Promise超神超簡単総括:前はいつもプロミスが神秘的だと感じていましたが、今日はチェット一峰大神のes 6を詳しく読んで、関連プロミスの原理も調べてみました.
プロフィール:
Promiseオブジェクトは、遅延計算と非同期計算に使用されます.Promiseオブジェクトはまだ未完成ですが、将来完成すると予想される操作を表しています.Promiseオブジェクトは戻り値のプロキシであり、この戻り値はプロミセオブジェクトの作成時には知られていないとは限らない.非同期動作の成功または失敗のための処理方法を指定することができます.これにより、非同期方法は、元の戻り値を含むpromiseオブジェクトを返す同期方法のように値を返すことができる.
どんな問題を解決しましたか?どうやって使いますか?
//              A,              B
    setTimeout(function(){
        //A  
        console.log('A');
        setTimeout(function() {
            //B  
            console.log('B');
        },300)
    },300);
//        ,      ,          
想像に難くないですが、順番にいくつかのアニメがあると、何重にもはまってしまいます.コードは縦方向に発展するのではなく、横方向に発展して、すぐに混乱してしまうので、管理できません.複数の非同期動作が強い結合を形成しているので、一つの操作があれば修正が必要であり、その上層反転関数と下層反転関数は全部修正されるかもしれない.この場合をコールバック関数地獄といいます.
Promiseオブジェクトはこの問題を解決するために提示されたものです.新しい文法機能ではなく、新しい書き方です.コールバック関数の入れ子をチェーン式に変えて呼び出します.Promiseの最大の問題はコード冗長です.元のタスクはPromiseによって包装されています.操作に関係なく、一目で見てもマンネリで、元の意味がよく分かりません.
(1)ブラウザの実現方式はPromise対応バージョンで実行できます.
var p = new Promise(function(resolve, reject){
  setTimeout(function(){
    //A  
    console.log('A');
    resolve();
  },300);
});

p.then(function(){
  setTimeout(function() {
      //B  
      console.log('B');
  },300);
});
(2)別の書き方(jQueryバージョン)
var deferred = $.Deferred();
setTimeout(function(){
  //A  
  console.log('A');
  deferred.resolve();
},300);

deferred.done(function() {
  setTimeout(function() {
    //B  
    console.log('B');
  },300)
});
promiseはコードを維持しやすくなります.同期コードを書くように、非同期コードを書きます.
プロミセの原理
プロミスとは、3つの状態のことです.観察者モードを利用して、特定の書き込みで対応する状態のイベントハンドラ関数を登録し、状態を更新し、登録した処理関数を呼び出すだけでいいです.この特定の方法はthen、done、fail、always…などの方法で、更新状態は、revove、reject方法です.
以下の簡単な実現:
/**
    /**
      * [3   ]
      * @type {String}
     */
    var PENDING = "pending";
    var RESOLVED = "resolved";
    var REJECTED = "rejected";
    /**
     * [Promise   ]
     *         fn,     ,resolve:    ; reject:    ;
     * state:     
     * doneList:         
     * failList:         
     * done:         
     * fail:         
     * then:              
     * always:             ,    
     * resolve:   state :RESOLVED,          
     * reject:   state :REJECTED,          
    */
    var Promise2 = (function() {
        var noop = function() {}
        function Promise(fn) {
            this.state = PENDING;
            this.doneList = [];
            this.failList = [];
            this.fn = fn;
            this.fn(this.resolve.bind(this), this.reject.bind(this)) //              
        }
        var p = {
            done: function(cb) {

                if (typeof cb == "function")
                    this.doneList.push(cb)
                return this;
            },
            fail: function(cb) {
                if (typeof cb == "function")
                    this.failList.push(cb);
                return this;
            },
            then: function(success, fail) {
                this.done(success || noop).fail(fail || noop)
                return this;
            },
            always: function(cb) {
                this.done(cb).fail(cb)
                return this;
            },
            resolve: function() {
                this.state = RESOLVED;
                var lists = this.doneList;
                for (var i = 0; i < lists.length;) {
                    lists[i].apply(this, arguments);
                    lists.shift();
                }
                return this;
            },
            reject: function() {
                this.state = REJECTED;
                var lists = this.failList;
                for (var i = 0; i < lists.length;) {
                    lists[0].apply(this, arguments);
                    lists.shift();
                }
                return this;
            }
        }
        for (var k in p) {
            Promise.prototype[k] = p[k]
        }
        return Promise;
    })();
//    
var p1 =  new Promise2(function(resolve,reject){    
    setTimeout(resolve,2000);
    console.log('p1',new Date);
 });
 p1.then(function(){
    console.log("end",new Date);
 }).always(function(){
    console.log('always',new Date);
 });
観察者モードを利用して、特定の書き込み方法によって、対応する状態のイベントハンドラ関数を登録し、状態を更新し、登録された処理関数を呼び出すだけでいいです.
説明:new Promise(fn)を呼び出すと、すぐに最初のパラメータfnが実行されます.上記の例では、まずthen(done,fail)が実行されます.対応するコールバック関数はそれぞれdoneListまたはfailListに追加され、alwaysに対応するパラメータは同時にdoneListとfailListに追加されます.非同期コードの実行が完了したら、resoveメソッドを呼び出します.この時はpromiseの状態をrevedに変えて、doneListの中のコール関数を実行します.もし実行に失敗したら、failメソッドを呼び出します.この時にpromiseの状態を変更します.そしてfailList内のコールバック関数を実行します.
4、ゲナートのちょっとしたアプリケーション
function * gen(m,n){
    for(let i=m;iyield i;
    }
}
console.log(...gen(1,10));

//  : 1 2 3 4 5 6 7 8 9
参考リンク:Promise:http://imweb.io/topic/565af932bb6a753a136242b0