promiseに対してよくある面接問題のまとめ分析

30517 ワード

1、Promiseを知っていますか?
1)Promiseを知る、Promiseは非同期プログラムの解決策であり、3つの状態があり、pending(進行中)、reolved(完了しました)、reject(失敗しました)があります.Promiseの状態がpendingからreolvedまたはrejectに変化する時、対応する方法を実行します.
2)Promisedの特徴は、非同期操作の結果、現在はどの状態かを決めることができます.他のジョブはこの状態を変えることができません.「Promise」の名前の由来です.また、状態が変われば、再度状態を変えることができません.
2、Promiseが解決する痛みの点は何ですか?
Promise解決の痛み点:
1)地獄に戻り、コードが維持しにくく、常に第一の関数の出力が第二の関数の入力という現象を解決するために、非同期操作関数の中の嵌合戻し(callback hell)問題を解決するために、コードが肥大し、可読性が悪く、チューニングのみで異常を処理することができる.
2)promiseは、複数の同時要求をサポートし、併発要求中のデータを取得することができる.
3)promiseは可読性の問題を解決できます.非同期の入れ子による可読性の問題は非同期の運行メカニズムによって引き起こされます.このようなコードは読みにくいです.
4)promiseは信頼問題を解決できます.返事が早すぎたり、返事が遅くなったり、呼び出し回数が少なすぎたり、多すぎたりします.promiseは一回しか決められないので、決議値は一つしかないです.決議後は変えられません.どのthenの返事も一回しか呼び出されないので、Promiseは信頼問題を解決できます.
3、Promiseが解決した痛み点は他の方法がありますか?あるなら列挙してください.
1)Promise解決の痛みは他の方法で解決できます.例えば、setTimeout、イベント監聴、コールバック関数、Generator関数、async/await
2)setTimeout:欠点は正確ではなく、一定時間後にタスクチームに参加することを確保するだけで、すぐに実行することは保証されていません.エンジンスタックのコード実行が完了した場合のみ、メインラインからタスクキューを読み込むことができます.
3)イベント傍受:タスクの実行はコードの順序ではなく、あるイベントが発生するかどうかによって異なります.
4)Generator関数は非同期動作を簡潔に表しているが、プロセス管理は不便である(すなわち、第一段階がいつ実行されるか、第二段階がいつ実行されるか).自動化の流れ管理はどのように実現しますか?
5)async/await
4、Promiseはどう使いますか?
1)Promiseの例を作成する
2)Promiseのインスタンスが生成されたら、then方法でそれぞれreolved状態とreject状態のコールバック関数を指定できます.
3)Promiseを利用できるtryとcatch方法で異常を予防する.
5、Promiseでよく使われる方法は何ですか?それらの役割は何ですか?
1)Promise.resove(value)
この方法は、value値で解析したPromiseオブジェクトを返します.この値がthenableであれば、戻ってきたPromiseオブジェクトはこのthenableのオブジェクトに従い、その最終状態を採用します.もし入ってきたvalue本体がPromiseオブジェクトであれば、このオブジェクトは、resolved/rejected/pending/settled方法の戻り値として他の場合に戻り、この値を成功状態としてPromiseオブジェクトに戻る.
2)Promise.reject
クラスの方法で、しかもreeveと唯一の違いは、帰ってきたpromiseオブジェクトの状態がrejectiedです.
3)Promise.prototype.then
例としての方法は、Promiseのためのコールバック関数を登録し、関数形式:Promise.resolveは前のジョブの返却結果であり、thenの関数は必ずreturn 1つの結果または新しいPromiseオブジェクトを登録してください.
4)Promise.prototype.cach
例としての方法、キャプチャ異常、関数形式:fn(vlaue){},value、errはcatch登録前のコールバックである.
5)Promise.race
複数のPromiseタスクを同時に実行し、最初に実行されたPromiseタスクの結果に戻ります.
6)Promise.all
クラス方法は、複数のPromiseタスクを同時に実行し、すべてのPromiseタスクの実行結果を配列で返します.Promiseタスクrejectがあると、rejectiedタスクの結果に戻ります.
6、Promiseのイベントサイクルの実行過程はどうなりますか?
1)イベントサイクル
コードの実行順序の観点から、プログラムの最初はコード順にコードを実行し、同期タスクが発生したら、直ちに実行します.非同期タスクが発生した場合、非同期関数を呼び出して非同期要求を開始するだけです.このとき、非同期タスクは非同期動作を開始し、実行が完了したらメッセージキューに並ぶ.プログラムはコード順に実行された後、待ちメッセージがあるかどうかを問い合わせる.ある場合は、メッセージキューから順にメッセージを実行スタックに入れて実行する.実行後、メッセージキューからメッセージを取得して実行し、繰り返します.メインスレッドの繰り返しにより、メッセージ、実行メッセージ、再メッセージ、再実行
2)promiseのイベントサイクル
Promiseは初期化時に、導入された関数は同期して実行され、thenコールバックを登録します.登録が完了したら、同期コードを継続して実行します.その前に、thenでのコールバックは実行されません.同期コードブロックが実行された後、イベントサイクルにおいて利用可能なプロミセ応答があるかどうかを検出します.もしあるなら、実行します.ないなら、次のイベントサイクルを続けます.
7、Promiseの業界実現にはどのようなものがありますか?
1)promiseは、複数の同時要求をサポートし、併発要求中のデータを取得することができる.
2)promiseは可読性の問題を解決できます.非同期の入れ子による可読性の問題は非同期の運行メカニズムによって引き起こされます.このようなコードは読みにくいです.
8、Promiseのpolyfillを手書きで書いてもいいですか?
1)Promsieのpolyfillのソースコードの実現
インスタンスコード:
function Promise(fn){
        //     Promise            
        if(!(this instanceof  Promise))
            throw  new TypeError('Promises must be constructed via new');
        //    Promise     fn       
        if(typeof fn !== "function")
            throw new TypeError('not a function');
        // _state     Promise   
        // Promise pending、fulfilled、rejected    ,    _state  0、1、2
        this._state = 0;
        // _handled      Boolean,    false,   Promise     
        this._handled = false;
        //  _value      Promise undefined,    undefined
        this._value = undefined;
        // _deferreds      Array,       ,        Function
        this._deferreds = [];
        //  Promise   fn        this    ,deResolve      
        doResolve(fn,this);
    }

function doResolve(fn, self) {
        // done           resolve() reject()     
        //  Promise      pending->fulfilled pending->rejected
        var done = false;
        try {
            //  fn        ,new Promise         fn(resolve,reject);
            fn(
                    function(value) {
                        if (done) return;
                        // done   true       
                        done = true;
                        resolve(self, value);
                    },
                    function(reason) {
                        if (done) return;
                        done = true;
                        reject(self, reason);
                    }
            );
        } catch (ex) {
            //   Promsie          , Promise    rejected  
            if (done) return;
            done = true;
            reject(self, ex);
        }
    }
2)Promiseのpolyfillの実現
インスタンスコード:
 const promiseStatusSymbol = Symbol("PromiseStatus");
    const promiseValueSymbol = Symbol("PromiseValue");
    // pending、fulfilled、rejected
    const status = {
        pending:"pending",
        fulfilled:"fulfilled",
        rejected:"rejected"
    };
    const transition = function(status){
    /*    var self = this;
        return function(value){
            this[promiseStatusSymbol] = status;
            this[promiseValueSymbol] = value;
        }*/

       return (value) => {
            this[promiseValueSymbol] = value;
            setStatus.call(this,status);
        }
    };

    //            
    //       pending   fulfilled,           fulfilled  
    //       pending   rejected,           rejected  
    const setStatus = function(status){
       this[promiseStatusSymbol] = status;
       if(status === status.fulfilled){
           this.deps.resolver && this.deps.resolver();
       }else if( status === status.rejected){
           this.deps.rejector && this.deps.rejector();
       }
    };

    //           ,        ,  pending  ,                
    const promise = function(resolver){
      if(typeof  resolver !== "function"){
          throw new TypeError("parameter 1 must be a function");
      }
        this[promiseStatusSymbol] = status.pending;
        this[promiseValueSymbol] = [];
        this.deps = [];
        resolver(
            //      resolve reject
            //              Promise         ,        
            transition.call(this,status.fulfilled),
            transition.call(this.status.rejected)
        );
    };

    // promise                       ,then       ,        
    promise.prototype.then = function(fulfilled,rejected){
        const self = this;
        return promise(function(resolve,reject){
           const callback = function () {
               //                 
               //         ,               
               const resoleValue = fulfilled(self[promiseValueSymbol]);
              // resolve(resoleValue);
              //          thenable  ,      then  ,       
              if(resoleValue && typeof resoleValue.then === "function"){
                  //   promise,        promise    
                  resoleValue.then(function(data){
                      resolve(data);
                  },function(err){
                      reject(err);
                  });
              }else{
                  // then           
                  //            promise          ,    promise     
                  //     promise       ,            promise   
                  resolve(resoleValue);
              }
           };
           const errCallback = function(){
               const rejectValue = rejected(self[promiseValueSymbol]);
               reject(rejectValue);
           };

           //   promise     
           //      promise   then          ,     promise           
           //         pending,  promise          ,                promise     
            if(self[promiseStatusSymbol] === status.fulfilled){
               return callback();
           }else if(self[promiseStatusSymbol] === status.rejected){
               return errCallback();
           }else if(self[promiseStatusSymbol] === status.pending){
               self.deps.resolver = callback;
               self.deps.rejector = errCallback;
           }
        });
    };
9、Promiseの問題?解決策
プロミスの問題は:
  • promiseが一旦実行されると、途中でキャンセルできなくなります.
  • promiseのエラーは外部では捉えられません.
  • promiseの内はどのように実行しますか?監視し始めるのは難しいです.
    解決策
  • これらの理由から、ES 7はより柔軟で多様なasyncを導入し、awaitは非同期
  • を処理する.
    10、手書きPromiseとajaxの結合?
    インスタンスコード:
    function promiseGet (url) {
      return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)
        xhr.onreadystatechange = function () {
          if (this.readyState === 4) {
            if (this.status === 200) {
              resolve(this.responseText,this)
            } else {
              let resJson = {
                code: this.status,
                response: this.response
              }
              reject(resJson, this)
            }
          }
        }
      })